mongodb - 将数组内容过滤为包含 $concatArrays 的查询

标签 mongodb mongodb-query aggregation-framework

鉴于此函数,我有一个要查询的数据集。数据如下所示:

db.activity.insert(
    {
        "_id" : ObjectId("5908e64e3b03ca372dc945d5"),
        "startDate" : ISODate("2017-05-06T00:00:00Z"),
        "details" : [
            {
                "code" : "2",
                "_id" : ObjectId("5908ebf96ae5003a4471c9b2"),
                "walkDistance" : "03",
                "jogDistance" : "01",
                "runDistance" : "08",
                "sprintDistance" : "01"
            }
        ]
    }
)

db.activity.insert(
    {
        "_id" : ObjectId("58f79163bebac50d5b2ae760"),
        "startDate" : ISODate("2017-05-07T00:00:00Z"),
        "details" : [
            {
                "code" : "2",
                "_id" : ObjectId("58f7948fbebac50d5b2ae7f2"),
                "walkDistance" : "01",
                "jogDistance" : "02",
                "runDistance" : "09",
                "sprintDistance" : ""
            }
        ]
    }
)

使用这个函数,感谢 Neil Lunn,我能够得到我想要的输出:

db.activity.aggregate([
  { "$project": {
    "_id": 0,
    "unique": {
      "$filter": {
        "input": {
          "$setDifference": [
            { "$concatArrays": [ 
              "$details.walkDistance",
              "$details.jogDistance",
              "$details.runDistance",
              "$details.sprintDistance"
            ]},
            []
          ]
        },
        "cond": { "$ne": [ "$$this", "" ] }
      }
    }
  }},
  { "$unwind": "$unique" },
  { "$group": {
    "_id": null,
    "uniqueArray": { "$addToSet": "$unique" }  
  }}
])

但是,我不能在开头添加匹配语句。

db.activity.aggregate([
  {$match: {"startDate" : ISODate("2017-05-06T00:00:00Z"), "details.code": "2" },
  {$unwind: '$details'},
  {$match: {"startDate" : ISODate("2017-05-06T00:00:00Z"), "details.code": "2" },
  { "$project": {
    "_id": 0,
    "unique": {
      "$filter": {
        "input": {
          "$setDifference": [
            { "$concatArrays": [ 
              "$details.walkDistance",
              "$details.jogDistance",
              "$details.runDistance",
              "$details.sprintDistance"
            ]},
            []
          ]
        },
        "cond": { "$ne": [ "$$this", "" ] }
      }
    }
  }},
  { "$unwind": "$unique" },
  { "$group": {
    "_id": null,
    "uniqueArray": { "$addToSet": "$unique" }  
  }}
])

因为它给出了错误信息:

> $concatArrays only supports arrays, not string

如何修改此查询以便添加 $match 语句?

最佳答案

不要$unwind您要提供给 $concatArrays 的数组.而是申请 $filter只提取匹配值。如前所述,我们可以只使用 $setUnion对于“唯一连接”,而不是:

db.activity.aggregate([
  { "$match": { "startDate" : ISODate("2017-05-06T00:00:00Z"), "details.code": "2" } },
  { "$project": {
    "_id": 0,
    "unique": {
      "$let": {
        "vars": {
          "filtered": {
            "$filter": {
              "input": "$details",
              "cond": { "$eq": [ "$$this.code", "2" ] }
            }  
          }
        },
        "in": {
          "$setDifference": [
            { "$setUnion": [ 
              "$$filtered.walkDistance",
              "$$filtered.jogDistance",
              "$$filtered.runDistance",
              "$$filtered.sprintDistance"
            ]},
            [""]
          ]
        } 
      }
    }
  }},
  { "$unwind": "$unique" },
  { "$group": {
    "_id": null,
    "uniqueArray": { "$addToSet": "$unique" }  
  }}
])

使用 $let由于您不需要指定多个 $map,因此语法更清晰和 $filter语句“内联”作为 $setUnion 的来源

关于mongodb - 将数组内容过滤为包含 $concatArrays 的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45809451/

相关文章:

javascript - 创建 MongoDB 集合中打开事务总数的聚合阶段

arrays - 如何删除与 MongoDB $pull 条件不匹配的元素?

mongodb - 返回所有字段 MongoDB 聚合

mongodb - 项目值作为键,嵌入文档作为 mongo 中的值

mongodb - 如何使用 mongodb 聚合返回字符串数组

mongodb - 如何搜索集合以在 MongoDB 中的文档之一中查找嵌套值

node.js - 在 mongodb 中 $facet 聚合后格式化数据

MongoDB - 将数组拆分为多个文档并用数组对象替换现有文档

node.js - 我如何为多个集合做 Mongodb 聚合过滤器?

node.js - 如何修复 "WARNING: The ` useMongoClient` 选项在 mongoose 5.x 中不再需要,请删除它。”