Как я могу отсортировать, прежде чем найти и ограничить в коллекции? - PullRequest
1 голос
/ 15 апреля 2019

Какой метод pymongo выполняется первым?sort или limit?

У меня есть большая коллекция, где мне нужно отфильтровать по определенной категории скидки ("X"), например:

{"discount_value": 1, "name": "promotion_1", "category": ["X"]},
{"discount_value": 10, "name": "promotion_10", "category": ["X", "Y"]},
{"discount_value": 15, "name": "promotion_15", "category": ["X", "Y", "Z"]}

Но запросдолжен отфильтровать все документы по discount_values, извлекая более крупные, скажем, мне нужно limit запрос по 2:

.find({"category": {"$in": ["X"]}})
.limit(2)
.sort("discount_value", pymongo.DESCENDING)

В этом примере я получу скидку 1 и 10, но то, что мне нужнобыло 10 и 15, как я могу отсортировать перед ограничением (если это возможно) без потери производительности (коллекция действительно большая)

1 Ответ

1 голос
/ 15 апреля 2019

sort() сначала применяется, а затем limit.

Прокрутите вниз до этого документа: https://docs.mongodb.com/manual/reference/method/db.collection.find/

Следующие операторы используют методы курсора limit () и sort():

db.bios.find (). Sort ({name: 1}) .limit (5)

db.bios.find (). Limit (5) .sort({имя: 1})

Два утверждения эквивалентны;т. е. порядок, в котором вы соединяете методы limit () и sort (), не имеет значения.Оба оператора возвращают первые пять документов, как определено в порядке возрастания сортировки по «имени».

Проверка порядка сортировки

Сортировка на самом деле работает правильно для меня,Используя MongoDB shell version v3.6.3 на сервере Ubuntu 18.04, я загрузил файл, подобный следующему:

[{"discount_value": 1, "name": "promotion_1", "category": ["X"]},
{"discount_value": 10, "name": "promotion_10", "category": ["X", "Y"]},
{"discount_value": 15, "name": "promotion_15", "category": ["X", "Y", "Z"]}]

, используя mongoimport --db test --collection test1 --drop --file testing.txt --jsonArray

В приглашении mongo я попытался найти и отсортировать по убыванию discount_value и увиделчто 15 было на вершине.

> db.test1.find({"category": {"$in": ["X"]}}).sort( {discount_value: -1} )
{ "_id" : ObjectId("5cb4beefea2d524413d8df57"), "discount_value" : 15, "name" : "promotion_15", "category" : [ "X", "Y", "Z" ] }
{ "_id" : ObjectId("5cb4beefea2d524413d8df56"), "discount_value" : 10, "name" : "promotion_10", "category" : [ "X", "Y" ] }
{ "_id" : ObjectId("5cb4beefea2d524413d8df55"), "discount_value" : 1, "name" : "promotion_1", "category" : [ "X" ] }

Предел тестирования

Обратите внимание, что limit до или после sort не влияет на результат.

Предел после сортировки дает тот же результат, что и предел до сортировки.

> db.test1.find({"category": {"$in": ["X"]}}).sort( {discount_value: -1} ).limit(2)
{ "_id" : ObjectId("5cb4beefea2d524413d8df57"), "discount_value" : 15, "name" : "promotion_15", "category" : [ "X", "Y", "Z" ] }
{ "_id" : ObjectId("5cb4beefea2d524413d8df56"), "discount_value" : 10, "name" : "promotion_10", "category" : [ "X", "Y" ] }

против.

> db.test1.find({"category": {"$in": ["X"]}}).limit(2).sort( {discount_value: -1} )
{ "_id" : ObjectId("5cb4beefea2d524413d8df57"), "discount_value" : 15, "name" : "promotion_15", "category" : [ "X", "Y", "Z" ] }
{ "_id" : ObjectId("5cb4beefea2d524413d8df56"), "discount_value" : 10, "name" : "promotion_10", "category" : [ "X", "Y" ] }

Производительность сортировки

Лучшее, что я могу вам сказать, - это использовать индексы, как предлагается в их руководстве https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/, и использовать объяснение, чтобы понять, гдеузкие места запроса существуют для вашей рабочей нагрузки с https://docs.mongodb.com/manual/reference/method/db.collection.explain/#db.collection.explain

...