У меня есть требование, чтобы при предоставлении списка объектов мне нужно было исключить те, которые уже существуют в моей базе данных.
Я пошел по традиционному маршруту, итерации по объектам и по одному, проверяя, существует ли объект в моей коллекции монго.
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();
Наиболее эффективный вариант:
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
(который, вероятно, находится в ОЗУ), и нет необходимости даже использовать фактические файлы данных.