首页 > 解决方案 > MongoDB过滤器查询日期数组返回空数组

问题描述

我有一个 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")
            ]
        }
    ]
}

我正在尝试获取在特定日期之后出售的所有变体。为此,我使用了以下 mongo 聚合查询,但在结果中,我得到了一个空的变体列表。

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")]
                    }]
                }
            }
        }
    }
}])

此查询适用于我尝试过的所有其他字段,但此日期列表除外。知道我做错了什么吗?

标签: mongodbmongodb-queryaggregation-framework

解决方案


由于variations.sold_dates是日期数组,因此您无法比较给定日期是否大于sold_dates。因此,您需要迭代变量.sold_dates数组的每个元素并检查大于 while 迭代,As$filter返回一个过滤器元素数组,然后您可以检查该数组的大小 > 0 以将变量对象添加到变量数组中$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-游乐场


推荐阅读