на стороне сервера установить пересечение в mongodb - PullRequest
2 голосов
/ 26 января 2011

В приложении, над которым я работаю, требуется сделать массивное пересечение наборов, чтобы было около 10-1 000 000 элементов или около того.Элементы, которые мы пересекаем, просто ObjectId.

Так, например, есть документ box, а внутри документа box - массив item_ids.Этот массив item_ids для каждого блока содержит 10-1 000 000 ObjectId.

Конечная цель здесь состоит в том, чтобы сказать, заданный блок A с ObjectId 4d3dc3898951498107000005 и блок B с ObjectId 4d3dc3898951498107000002, какие item_ids у них общие?

Вот как я это делаю:

db.boxes.distinct("item_ids", {'_id' : {$in : [ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}})

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

Во-вторых, любопытно, как это будет вести себя в закрытой среде?Будут ли монго выполнять часть запроса на монгоде, который ему необходим, и магически агрегировать мой результат?

Наконец, если вышеупомянутое является нормальным, это также разумно делать:

db.items.find({'_id' : { $in : db.eval(function() {return db.boxes.distinct("item_ids", {_id:{$in:[ObjectId("4d3dc3898951498107000005"), ObjectId("4d3dc3898951498107000002")]}}); }) }}) 

Который в основном будет находить, какие элементы, как у блока A, так и у блока B, общими, а затем материализует их в объекты в одном запросе на стороне сервера.Похоже, это также работает с .limit и .skip для эффективной реализации разбиения на страницы набора данных.

В любом случае, любая обратная связь ценна, спасибо!

1 Ответ

3 голосов
/ 26 января 2011

Я думаю, вы можете пересмотреть свою схему.Если у вас есть 1 000 000 ObjectID в массиве по 12 байтов каждый, каждый по 12 МБ, даже не считая издержки BSON, которые могут быть значительными для больших массивов * (вероятно, еще 8 МБ или около того)В версии 1.8 мы увеличиваем максимальный размер документа с 4 МБ до 16 МБ, но даже этого недостаточно для объектов, которые вы хотите сохранить.

* По историческим причинам мы храним stingified индекс для каждого элемента вмассив, который хорош, когда у вас <100 элементов, но складывается, когда вам нужно 6 или 7 цифр. </p>

...