2015-04-08 3 views
4

С версии 1.10 драйвера .NET я мог бы сделать что-то вроде этого, чтобы получить максимальную отметку времени в oplog коллекции:Найти максимум в коллекции MongoDB с использованием .Net Driver 2

this.oplogCollection.AsQueryable<OplogEntry>().Max(o => o.ts); 

Как я могу сделать что с новым драйвером 2.0? Документация в основном отсутствует или не полезна, поэтому я надеюсь, что некоторые инсайдеры могут пролить свет здесь.

ответ

1

EDIT: Не уверен, что есть лучший способ, но это работает. Я не нашел способ легко реализовать оператор $ max.

var list = await collection.Aggregate().SortByDescending((a) => a["field"]).FirstAsync(); 
+0

Да, кроме Max, определенного на интерфейсе IMongoCollection. Где конкретно вы нашли примеры? – hholtij

+0

Мой плохой я предполагал, что это IQueryable. Я обновил свой ответ с помощью решения, которое я нашел. Надеюсь, это сработает для вас. –

+0

Спасибо, Janic. Это быстрое и, надеюсь, временное решение, которое я использую уже. Это довольно медленно, тo. Медленнее исходного запроса Max. Сортировка неиндексированной коллекции, такой как oplog, является дорогостоящей операцией, тем более, что oplog растет очень быстро. – hholtij

2

Вы можете попробовать это:

var result = await collection.Find(x => true).SortByDescending(d => d.ts).Limit(1).FirstOrDefaultAsync(); 

BTW $max не дает вам наибольшее значение как в Linq или SQL, он определяет верхний монопольно связанный из Find. Documentation here

+0

Спасибо, Д.Росадо, но это то же самое решение, которое предложил Яник и которое я уже реализовал уже как промежуточное решение. Это не будет работать для производства, так как безумие сортировать весь всплеск (который может быть огромным), чтобы получить последнюю запись. $ max не будет работать, потому что oplog не имеет индексов, а $ max работает только с индексированными полями. Исходное решение для 1.10 имело Linq Max. – hholtij

2

Вот самый быстрый способ получить доступ к последней записи в oplog я нашел до сих пор:

this.oplogCollection.Find(new BsonDocument()).Sort(new BsonDocument("$natural", -1)).FirstOrDefaultAsync() 

Он сортирует oplog в обратном естественном порядке и так как естественный порядок в oplog является восходящей меткой времени , захват последнего элемента дает мне максимум.

Этот метод очень быстрый, и из первых экспериментов он не зависит от размера oplog, поскольку фактическая сортировка не происходит.

Другие решения уменьшат производительность с использованием размера oplog.

0

Поскольку MongoDB.Driver 2.0 наилучший подход заключается в использовании FindOptions экземпляр с заданными Limit и Sort полей:

var options = new FindOptions<OplogEntry, OplogEntry> 
{ 
    Limit = 1, 
    Sort = Builders<OplogEntry>.Sort.Descending(o => o.ts) 
}; 

var max = (await oplogCollection.FindAsync(FilterDefinition<OplogEntry>.Empty, options)).FirstOrDefault(); 

Sort и Limit PARAMS обрабатываются на стороне сервера. Поэтому такая операция очень эффективна, и только один результат передается клиенту.

Смежные вопросы