#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. Вы имеете в виду добавление другого индексного поля в каждый документ?