MongoDB:从数组中单独获取所有$ matched元素

时间:2018-11-29 14:06:18

标签: mongodb mongoose nosql mongodb-query aggregation-framework

我正在尝试单独获取所有匹配的元素,here是示例数据和查询。

// json
[
  {
    "name": "Mr Cool",
    "ican": [
      {
        "subcategory": [
          {
            "id": "5bffdba824488b182ec86f8d", "name": "Cricket"
          },
          {
            "id": "5bffdba824488b182ec86f8c", "name": "Footbal"
          }
        ],
        "category": "5bffdba824488b182ec86f88",
        "name": "Sports"
      }
    ]
  }
]

// query
db.collection.aggregate([
  {
    "$match": {
      "ican.subcategory.name": { $in: ["Cricket","Football"] }
    }
  },
  {
    "$project": { "_id": 1, "name": 1, }
  }
])

我得到的是合并结果,我需要单独的比赛记录。我尝试了$all$elementMatch,但得到了相同的响应。我如何获得如下结果。我使用$aggregate是因为我将使用$geoNear管道来获取附近的用户。

// current result
[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "name": "Mr Cool"
  }
]

// expected result
[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "name": "Mr Cool",
    "subcategory: "Cricket"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "name": "Mr Cool",
    "subcategory: "Footbal"
  }
]

谢谢

2 个答案:

答案 0 :(得分:1)

尝试这个Mongo Playground

db.col.aggregate([
    {"$unwind" : "$ican"},
    {"$unwind" : "$ican.subcategory"},
    {"$match" : {"ican.subcategory.name": { "$in": ["Cricket","Football"] }}},
    {"$group" : {"_id" : null,"data" : {"$push" : {"_id" : "$_id","name" : "$name","subcategory" : "$ican.subcategory.name"}}}},
    {"$unwind" : "$data"},
    {"$replaceRoot" : {"newRoot" : "$data"}}
])

答案 1 :(得分:1)

您可以在不使用$unwind的情况下使用以下聚合,以提高性能

db.collection.aggregate([
  { "$match": { "ican.subcategory.name": { "$in": ["Cricket","Football"] }}},
  { "$project": {
    "ican": {
      "$reduce": {
        "input": "$ican",
        "initialValue": [],
        "in": {
          "$concatArrays": [
            { "$filter": {
              "input": {
                "$map": {
                  "input": "$$this.subcategory",
                  "as": "s",
                  "in": { "name": "$name", "subcategory": "$$s.name" }
                }
              },
              "as": "fil",
              "cond": { "$in": ["$$fil.subcategory", ["Football"]] }
            }},
            "$$value"
          ]
        }
      }
    }
  }},
  { "$unwind": "$ican" },
  { "$replaceRoot": { "newRoot": "$ican" }}
])