Предполагая, что я полностью понимаю, что вы хотите, это должно быть так просто:
Сначала поместите нисходящий индекс в поле LastAuditId
:
db.collection.createIndex{ "LastAuditId": -1 /* for sorting */ }
Или даже расширьтеиндекс для других полей, которые есть в вашем фильтре:
db.collection.createIndex{ "Status": 1, "LastAuditId": -1 /* for sorting */ }
Однако убедитесь, что вы понимаете , как индексы могут / не могут поддерживать определенные запросы .И всегда используйте объяснение () , чтобы увидеть, что на самом деле происходит.
Следующим шагом является осознание того, что вы всегда должны фильтровать как можно больше, чем самый первый шаг, чтобы уменьшить количествотребуется сортировка.
Итак, если вам нужно, например, отфильтровать по Name
, то непременно сделайте это в качестве самого первого шага, если это позволяют ваши бизнес-требования.Будьте осторожны, однако, что фильтрация в начале меняет вашу семантику в том смысле, что вы будете получать последние измененные документы для каждого Id
, который прошел предыдущий этап $match
, в отличие от последних документов на каждый Id
, которые происходяттакже пройти следующую стадию $match
.
В любом случае, что наиболее важно, после того, как вы получили отсортированный комплект, вы можете легко и быстро получить последний полный документ, используя $group
с $first
, который- с правильным индексом на месте - больше не будет выполнять сканирование коллекции (сейчас это будет сканирование индекса и, следовательно, намного быстрее).
Наконец, вы хотите запустить эквивалент следующего запроса MongoDBчерез C #, используя переменную $$ ROOT , чтобы избежать повторного запроса (я могу собрать необходимый код для вас, как только вы опубликуете типы Audit
, Auditable
и IMongoAuditable
, а такжелюбые потенциальные сериализаторы / соглашения):
db.getCollection('collection').aggregate({
$match: {
/* some criteria that you currently get in the "Expression<Func<BsonDocument, bool>> filter" */
}
}, {
$sort: {
"ModifiedDate": -1 // this will use the index!
}
}, {
$group: {
"_id": "$Id",
"document": { $first: "$$ROOT" } // no need to do a separate subsequent query or a $max/$min across the entire group because we're sorted!
}
}, {
$match: { // some additional filtering depending on your needs
"document.Status": { $ne: "Delete" }
}
})
И наконец, учтите, что было бы неплохо перейти на последнюю версию MongoDBпотому что в настоящее время они прилагают много усилий для оптимизации таких случаев агрегирования, как у вас, например: https://jira.mongodb.org/browse/SERVER-9507