Я сохраняю документы для игр в MongoDB. Среди прочего, документы содержат имя игрока (имя), время окончания игры (endMS) и тип игры (тип). Тип может иметь одно из пяти разных значений.Почему MongoDB использует scanAndOrder здесь?
Мне нужно найти все готовые игры игрока, отсортированного по времени окончания игры и для всех законченных игр игрока с определенным типом игры, также отсортированным по времени окончания игры.
Примеры для обоих запросов являются
db.games.find ({имя: "Стефан", endMS: {$ Gt: 0}}). Сортировки ({endMS: -1})
и
db.games.find ({имя: "Стефан", тип: "л", endMS: {$ Gt: 0}}). сортировки ({endMS: -1})
Вы можете использовать индексы
db.games.ensureIndex ({имя: 1, endMS: -1})
и
db.games.ensureIndex ({имя : 1, тип: 1, endMS: -1})
для быстрого доступа.
Теперь я пытаюсь ладить только с одним индексом:
db.games.ensureIndex ({имя: 1, endMS: -1, тип: 1})
первый запрос или курс все еще отлично. Идея второго запроса заключается в том, что Mongo может потребоваться пропустить некоторые записи при сканировании индекса, но только нужно получить доступ к документам, которые, наконец, будут возвращены запросом, потому что «тип» уже может быть проверен в индексе. Это должно быть достаточно быстро для моих нужд.
Однако, используя объяснение(), MongoDB сообщает мне, что при запросе базы данных необходимо «scanAndOrder».
db.games.find ({имя: "Стефан", тип: "л", endMS: {$ Gt: 0}}) рода.. ({EndMS: -1}) объясняет()
{
"cursor" : "BtreeCursor name_1_endMS_-1_type_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 22,
"nscannedObjectsAllPlans" : 4,
"nscannedAllPlans" : 25,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"name" : [
[
"Stefan",
"Stefan"
]
],
"endMS" : [
[
Infinity,
0
]
],
"type" : [
[
"bli",
"bli"
]
]
},
"server" : "localhost:27017",
"filterSet" : false
}
nscannedObjects и nscanned являются, как и ожидалось, как описано выше, но мне интересно, почему Монго говорит scanAndOrder: верно.
В соответствии с документами: «scanAndOrder - это логическое значение, которое истинно, когда запрос не может использовать порядок документов в индексе для возврата отсортированных результатов: MongoDB должен сортировать документы после получения документов с помощью курсора».
Насколько я понял, документы должны быть заказываются в индексе, только некоторые из них должны быть пропущены, что не влияет на порядок.
Так почему MongoDB использует scanAndOrder здесь?
В какой версии MongoDB вы используете? Странно, что у вас есть истинный «scanAndOrder» и ложный «indexOnly». Я бы сказал, что ваш запрос включен в индекс ... – rubenfa
Я использую MongoDB 2.6.0-rc0. Поиск не может быть indexOnly, потому что он возвращает весь документ. Это только «indexOnly» в том смысле, что ему не нужно сканировать документ, чтобы узнать, соответствует ли он запросу. – StefanMK
Странно, я добавил {_id: 0, name: 1} в качестве параметра проецирования к запросу, и это также не сделает запрос indexOnly. Возможно, что-то такое, что «тип» на самом деле «tc.type», поэтому он взят из встроенного документа (я просто хотел сделать проблему более понятной здесь). Я помню, что в структуре агрегации MongoDB существует проблема с coverIndexes, когда одна часть индекса поступает из встроенного документа. Но это также влияет на scanAndOrder? – StefanMK