Запрос фильтра MongoDB на массив дат Возвращает пустой массив - PullRequest
1 голос
/ 04 марта 2020

У меня есть документ MongoDB, содержащий информацию о продукте и его вариантах, пример структуры приведен ниже.

{
    "site_id": 3,
    "status": 2,
    "tags": [],
    "title": "WORTHBUY Bento Lunch Box for Kids, 2 Compartments Stainless Steel Square Lunch Box with Portable Cutlery, Portion Control Food Storage Container Leakproof, BPA Free(Pink)",
    "total_sold_count": 3,
    "amount_of_variations": 3,
    "variations": [{
            "price": 9.66,
            "shipping_price": 0,
            "quantity": 0,
            "sold_count": 1,
            "sold_dates": [
                ISODate("2020-03-03T17:00:00.000-07:00")
            ]
        },
        {
            "price": 18.42,
            "shipping_price": 0,
            "quantity": 0,
            "sold_count": 1,
            "sold_dates": [
                ISODate("2020-03-03T17:00:00.000-07:00")
            ]
        },
        {
            "price": 18.42,
            "shipping_price": 0,
            "quantity": 0,
            "sold_count": 1,
            "sold_dates": [
                ISODate("2020-03-03T17:00:00.000-07:00"),
                ISODate("2020-03-09T20:30:56.000-06:00")
            ]
        }
    ]
}

Я пытаюсь получить все варианты, которые были проданы после указанного c дата. Чтобы выполнить sh, я использовал следующий агрегированный запрос mon go, но в результате я получил пустой список вариантов.

db.products.aggregate([{
    $match: {
        "variations.sold_dates": {
            $gt: ISODate("2020-03-05 00:00:00")
        }
    }
}, {
    $addFields: {
        "variations": {
            $filter: {
                input: "$variations",
                as: "variations",
                cond: {
                    $and: [{
                        $gt: ["$$variations.sold_dates", ISODate("2020-03-05 00:00:00")]
                    }]
                }
            }
        }
    }
}])

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

Ответы [ 2 ]

2 голосов
/ 04 марта 2020

Поскольку Вариации.sold_dates - это массив дат, Вы не можете сравнивать данную дату больше, чем sold_dates . Таким образом, вам нужно выполнить итерацию для каждого элемента массива Варианты. массив объектов вариаций в $addFields. Попробуйте этот запрос:

db.collection.aggregate([
  {
    $match: {
      "variations.sold_dates": {
        $gt: ISODate("2020-03-05T00:00:00Z")
      }
    }
  },
  {
    $addFields: {
      "variations": {
        $filter: {
          input: "$variations",
          as: "variation",
          cond: {
            $gt: [
              {
                $size: {
                  $filter: {
                    input: "$$variation.sold_dates",
                    cond: {
                      $gt: [
                        "$$this",
                        ISODate("2020-03-05T00:00:00.000Z")
                      ]
                    }
                  }
                }
              },
              0
            ]
          }
        }
      }
    }
  }
])

Тест: MongoDB-Playground

0 голосов
/ 04 марта 2020

Другое решение:

db.collection.aggregate([
   {
      $set: {
         "variations": {
            $filter: {
               input: "$variations",
               as: "variation",
               cond: {
                  $anyElementTrue: {
                     $map: {
                        input: "$$variation.sold_dates",
                        in: { $gt: ["$$this", ISODate("2020-03-05T00:00:00.000Z")] }
                     }
                  }
               }
            }
         }
      }
   }
])

В зависимости от ваших требований вы можете заменить $anyElementTrue на $allElementsTrue

...