Запросы MongoDB — $условие по элементу в массиве

#mongodb #mongodb-query #aggregation-framework #spring-data-mongodb

Вопрос:

У меня есть следующий конвейер агрегирования, состоящий из одного $redact шага: (который должен возвращать все продукты, для которых зарегистрированное количество продаж превышает запасы)

 $redact:
{
  $cond: [
    { $gt: ["$sales", "$productInfo.0.stock"] },
    "$KEEP",
    "$PRUNE"
  ]
}
 

(приведенный выше синтаксис специфичен для Compass, поэтому здесь нет проблем)

Где сущности выглядят примерно так:

 {
   _id: 123,
   sales: 60,
   price: 80,
   productInfo: [
      {
         stock: 100
      }
   ]
}
 

Однако приведенный выше запрос, похоже, не работает. Я предполагаю , что проблема вызвана сравнением с $productInfo.0.stock , поскольку замена его другим прямым атрибутом сущности (например price ) выполняется без каких-либо проблем.

Как следует указывать такой запрос ( $cond по тому, $gt где одно из значений находится в массиве/списке)?

Комментарии:

1. Можете ли вы поделиться одним примером документа, хранящегося в коллекции, и желаемыми результатами?

Ответ №1:

productionInfo.0.stock Синтаксис-это язык запросов Mongo (MQL), который может использоваться в a $match или a find .

Эта конкретная конструкция недоступна при использовании синтаксиса агрегации, например "$fieldName" . Вместо этого вам нужно использовать $arrayElemAt , но , к сожалению, это не поддерживает доступ к полям в ссылочном элементе.

Чтобы получить то, что вы хотите, вам нужно будет добавить поле на предыдущем этапе, которое извлекает нужный элемент из массива, ссылаться на этот объект в $redact, а затем спроецировать временное поле, например:

 {$addFields: {firstProduct: {$arrayElemAt: [ "$productInfo", 0 ]}}},
{$redact:{
  $cond: [
    { $gt: ["$sales", "$productInfo.0.stock"] },
    "$KEEP",
    "$PRUNE"
  ]
}},
{$project: {firstProduct: 0}}