#c# #.net #mongodb #mongodb.driver
#c# #.net #mongodb #mongodb.driver
Вопрос:
У меня возникла проблема с созданием фильтра для получения объекта по условию во вложенном массиве.
Мои модели:
public class ProductPriceInStore
{
[BsonId]
public ObjectId Id { get; set; }
public ObjectId store { get; set; }
public ObjectId product { get; set; }
public string measurementUnit { get; set; }
public IList<ProductPrices> prices { get; set; }
}
public class ProductPrices
{
public double? actualPrice { get; set; }
public double? originalPrice { get; set; }
}
Что я хочу сделать, так это найти весь ProductPriceInStore, который содержит ProductPrice с actualPrice больше, чем originalPrice
Я использую nugget MongoDB.Driver 2.7.3 в своем проекте
Комментарии:
1. Посмотрите
ElemMatch
.2. Я пытался использовать его следующим образом: var filter = Builders<ProductPriceInStore> . Фильтр. elemMatch(y => y.prices, x => x.actualPrice > x.originalPrice); но это дало мне ошибку ‘Неподдерживаемый фильтр: ({document}{actualPrice}> {document}{originalPrice}). Мне нужно будет подробнее изучить elementMatch
Ответ №1:
db.ProductPriceInStore.find({$expr:{$gt:["$prices.actualPrice", "$prices.originalPrice"]}})
Ответ №2:
Вы можете использовать Linq query selector: если у вас есть список ProductPriceInStore, так что вы можете сделать:
ProductPriceInStoreList.Where(item => item.prices.Where(p => p.actualPrice > p.originalPrice ))
Комментарии:
1. у меня это как IMongoCollection. Я могу каким — то образом получить доступ к linq с помощью . Найдите метод ant, тогда я не знаю, как его определить, обычно это заканчивается ошибкой, что драйвер не может перевести команду. И я не могу загрузить эту коллекцию в память — я имею в виду с помощью «.ToList», потому что в этой коллекции более 5 000 000 записей…
Ответ №3:
вы можете получить желаемый результат с помощью следующего конвейера агрегации, $elemMatch
который нельзя использовать для сравнения значений полей во вложенных объектах (afaik).
db.ProductPriceInStore.aggregate(
[
{
$set: {
prices: {
$filter: {
input: "$prices",
cond: { $gt: ["$$this.actualPrice", "$$this.originalPrice"] }
}
}
}
},
{
$match: {
prices: { $gt: [0, { $size: "$prices" }] }
}
}
])
однако это было бы неэффективно. гораздо лучшим подходом было бы сохранить логическое свойство IsGreaterThanOriginalPrice
во время создания / сохранения вложенных элементов, и в этом случае вы можете легко использовать ElemMatch
его без особых хлопот.