Как удалить дубликаты документов MongoDB в коллекции буферов

#php #mongodb

#php #mongodb

Вопрос:

Я использую PHP Mongo 3.2.9 для своего проекта.

В этом проекте хранятся миллионы документов со множеством новых записей каждый день. Для оптимизации моей базы данных я использую коллекцию буферов, в которой хранятся идентификаторы записей, чтобы сохранять только новые документы в другой коллекции.

Для этого я пытаюсь разработать оптимизированный скрипт, который удаляет дублирующиеся записи, заботясь об удалении документов с меньшим количеством полей.

Коллекция буферов (без _id) :

 [
{
    label : "red",
    added : true
},
{
    label : "yellow",
    added : true
},
{
    label : "pink"
},
{
    label : "blue"
},
{
    label : "green"
},
{
    label : "grey"
},
{
    label : "pink",
    added : true
},
{
    label : "blue",
    added : true
},
{
    label : "green"
},
{
    label : "red"
},
{
    label : "blue"
}
]
  

Используя приведенный выше пример :
Вот коллекция цветов. У некоторых есть статус «добавлено», у других нет.
Мне бы хотелось, чтобы скрипт разрешал только один документ для каждого цвета, и особенно тот, у которого есть поле «добавлено: true», если оно существует.

Вот как должен быть результат :

 [
{
    label : "red",
    added : true
},
{
    label : "yellow",
    added : true
},
{
    label : "green"
},
{
    label : "grey"
},
{
    label : "pink",
    added : true
},
{
    label : "blue",
    added : true
}
]
  

Я представлял себе процесс с помощью 2 php-скриптов :

 $m = new MongoDBDriverManager('mongodb://localhost:27017/?w=0');

// script 1  
$filter = ['added' => [ '$exists' => true ]];

$q = new MongoDBDriverQuery($filter);
$rows = $m->executeQuery('db.buffer', $q);

forEach ($rows as $r) {

    $b = new MongoDBDriverBulkWrite;

    $f = [ 'label' => $r->label, 'added' => [ '$exists' => false ] ];

    $b->delete($f);

    if (count($b) > 0) {
        $result = $m->executeBulkWrite('db.buffer', $b);
    }
}

// script 2:
$filter = ['added' => [ '$exists' => false ]];

$q = new MongoDBDriverQuery($filter);
$rows = $m->executeQuery('db.buffer', $q);

forEach ($rows as $r) {

    $b = new MongoDBDriverBulkWrite;

    $f = [ '_id' => [ '$gt' => $r->_id ], 'label' => $r->label];

    $b->delete($f);

    if (count($b) > 0) {
        $result = $m->executeBulkWrite('db.buffer', $b);
    }   
}
  

Но на самом деле этот путь слишком длинный (особенно второй сценарий), и я получил фатальную ошибку, потому что время обработки закончилось.

Я уверен, что есть лучший способ улучшить процесс.

Спасибо, что помогли мне решить эту проблему.

Комментарии:

1. Рассматривали ли вы возможность использования уникального индекса для поля цвета?

2. Вы имеете в виду добавление другого индексного поля в каждый документ?

3. docs.mongodb.com/v3.2/core/index-unique