查询文档数组(棘手)

Querying an Array of docs (tricky)

这里是初学者。给我一个 find() 查询,它将给出“Sam”

的年龄

需要查询承包商文档数组。 “名称”字段是一个文档,其名称为:“Sam”。但是“年龄”字段不在这个“姓名”文档中,它在上一级文档中。

需要广泛的查询,即使“Sam”的位置是大型数据库中的任意随机位置也能正常工作

预期输出:

{age : 22}
{
    "name" : "Apples",
    "qty" : 120,
    "from" : [
        "USA",
        "Brazil",
        "Russia"
    ],
    "contractors" : [
        {
            "name" : {
                "fname" : "Sam",
                "lname" : "McGregor"
            },
            "age" : 22
        },
        {
            "name" : {
                "fname" : "zxc",
                "lname" : "asd"
            },
            "age" : 32
        }
    ]
}

查询 1

  • 查找具有 fname=samlname= McGregor 的承包商成员(如果您只想要名称,请删除名称过滤器)
  • 并计划保持这个匹配成员的年龄
  • 使用你driver的findOne方法,因为无论如何年龄都是一样的

Test code here

find({
  "contractors": {
    $elemMatch: {
      "name.fname": "Sam",
      "name.lname": "McGregor"
    }
  }
},
{
  "contractors.age.$": 1,
  "_id": 0
})

查询2

  • 聚合解决方案
  • 匹配 fname,lfname(需要多键索引快)
  • 限制为 1,因为无论如何年龄都是一样的
  • 过滤器从数组中查找 Sam
  • 项目只保留他的年龄

*和上面的区别是元素匹配,把匹配到的成员保存在$中,这样我们就不用re-search了。 但是如果你有多键索引,这个解决方案会很快。

Test code here

aggregate(
[{"$match":  
    {"$and": 
      [{"contractors.name.fname": {"$eq": "Sam"}},
        {"contractors.name.lname": {"$eq": "McGregor"}}]}},
  {"$limit": 1},
  {"$project": 
    {"_id": 0,
      "age": 
      {"$getField": 
        {"field": "age",
          "input": 
          {"$first": 
            {"$filter": 
              {"input": "$contractors",
                "cond": 
                {"$and": 
                  [{"$eq": ["$$this.name.fname", "Sam"]},
                    {"$eq": ["$$this.name.lname", "McGregor"]}]}}}}}}}}])