首页 > 解决方案 > 在 Mongodb 中查询嵌套的 Json 并获取所有结果

问题描述

我在 mongo db 中有一个嵌套的 Json 文档,如下所示: /* 1 */

{
    "_id" : ObjectId("5bf159cc6bf6ab0ac374f80c"),
    "name" : "Jack",
    "age" : "30",
    "info" : {
        "0" : {
            "status" : "true",
            "name" : "luffy"
        },
        "1" : {
            "status" : "true",
            "name" : "sanji"
        },
        "2" : {
            "status" : "false",
            "name" : "zoro"
        }
    }
}

/* 2 */
{
    "_id" : ObjectId("5bf15f286bf6ab0ac374f8ed"),
    "name" : "Mack",
    "age" : "33",
    "info" : {
        "0" : {
            "status" : "true",
            "name" : "naruto"
        },
        "1" : {
            "status" : "true",
            "name" : "sakura"
        },
        "2" : {
            "status" : "false",
            "name" : "sasuke"
        }
    }
}

现在我想做的是查询并获取 status = 'true' 的结果。经过一番谷歌搜索后,我开始知道如何查询嵌套文档并提出了一个示例查询:

db.getCollection('test').find({"info.0.status":"true"})

但是正如您从上面的查询中知道的那样,查询只会从第 0 个数组中获取适当的结果,我如何让查询遍历数组并返回带有 "status":"true" 的文档。我也是新手Mongodb,请忽略任何错误。

标签: jsonmongodb

解决方案


如果您查询db.getCollection('test').find({"info.0.status":"true"}),它将返回为:

{
    "_id" : ObjectId("5bf159cc6bf6ab0ac374f80c"),
    "name" : "Jack",
    "age" : "30",
    "info" : {
        "0" : {
            "status" : "true",
            "name" : "luffy"
        },
        "1" : {
            "status" : "true",
            "name" : "sanji"
        },
        "2" : {
            "status" : "false",
            "name" : "zoro"
        }
    }
}

/* 2 */
{
    "_id" : ObjectId("5bf15f286bf6ab0ac374f8ed"),
    "name" : "Mack",
    "age" : "33",
    "info" : {
        "0" : {
            "status" : "true",
            "name" : "naruto"
        },
        "1" : {
            "status" : "true",
            "name" : "sakura"
        },
        "2" : {
            "status" : "false",
            "name" : "sasuke"
        }
    }
}

但是,如要求中所述,您需要将数据建模为:

[
  {
    "_id": ObjectId("5bf159cc6bf6ab0ac374f80c"),
    "name": "Jack",
    "age": "30",
    "info": [
      {
        "status": "true",
        "name": "luffy"
      },
      {
        "status": "true",
        "name": "sanji"
      },
      {
        "status": "false",
        "name": "zoro"
      }
    ]
  },
  {
    "_id": ObjectId("5bf15f286bf6ab0ac374f8ed"),
    "name": "Mack",
    "age": "33",
    "info": [
      {
        "status": "true",
        "name": "naruto"
      },
      {
        "status": "true",
        "name": "sakura"
      },
      {
        "status": "false",
        "name": "sasuke"
      }
    ]
  }
]

使用$filter,它返回预期的结果:

db.collection.aggregate([
  {
    $project: {
      items: {
        $filter: {
          input: "$info",
          as: "info",
          cond: {
            $eq: [
              "$$info.status",
              "true"
            ]
          }
        }
      }
    }
  }
])

示例响应:

[
  {
    "_id": ObjectId("5bf159cc6bf6ab0ac374f80c"),
    "items": [
      {
        "name": "luffy",
        "status": "true"
      },
      {
        "name": "sanji",
        "status": "true"
      }
    ]
  },
  {
    "_id": ObjectId("5bf15f286bf6ab0ac374f8ed"),
    "items": [
      {
        "name": "naruto",
        "status": "true"
      },
      {
        "name": "sakura",
        "status": "true"
      }
    ]
  }
]

推荐阅读