MongoDB Самый эффективный способ выполнить этот запрос

1

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

Я пошел по традиционному маршруту, итерации по объектам и по одному, проверяя, существует ли объект в моей коллекции монго.

foreach (PickerPlace pickerPlace in param)
{
    string id = pickerPlace.id;
    IMongoQuery query = Query<Place>.Where(p => p.Id == id);
    int count = this.context.Place.AsQueryable().Count(q => query.Inject());
    if (count == 0)
    {
        filteredResults.Add(pickerPlace);
    }
}

return filteredResults;

Является ли это самым эффективным способом делать то, что я пытаюсь достичь, так или иначе мне кажется, что я должен выполнять какую-то периодическую операцию.

Большое спасибо

Обновить:

Я обнаружил, что следующий код намного эффективнее, но мне все же нравятся предложения по дальнейшему улучшению.

List<string> ids = param.Select(p => p.id).ToList();
var results = this.context.Place.Find(Query.In("Id", new BsonArray(ids))).ToList();
Теги:
performance
mongodb-query
mongodb-.net-driver

1 ответ

1
Лучший ответ

Наиболее эффективный вариант:

var newIds = new HashSet<string>(param.Select(p => p.Id));
newIds.ExceptWith(
    places.Find(Query<Place>.In(p => p.Id, newIds))
        .SetFields(Fields<Place>.Include(p => p.Id))
        .Select(p => p.Id));

HashSet позволяет эффективно сравнивать, используя элемент GetHashCode (и Equals). Запрос возвращает все существующие элементы в одном запросе. SetFields возвращает только идентификаторы, поэтому используется встроенный индекс _id (который, вероятно, находится в ОЗУ), и нет необходимости даже использовать фактические файлы данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню