【问题标题】:How to fetch the nested record of another nested list of a document?如何获取文档的另一个嵌套列表的嵌套记录?
【发布时间】:2017-07-19 11:25:35
【问题描述】:

我在检索另一个嵌套列表的嵌套文档对象时遇到了困难。请帮我解决同样的问题。我的mongoDB文档如下:

{ 
"_id" : "PT5", 
"departmentId" : "DEPT5", 
"subDepartmentList" : [
    {
        "subDepartmentId" : "SUBDEPT19", 
        "subDepartmentName" : "X-Ray",  
        "labServiceList" : [
            {
                "_id" : "123abc", 
                "subDepartmentId" : "SUBDEPT19", 
                "labServiceName" : "serviceOne"
            }, 
            { 
                "_id" : "123def", 
                "subDepartmentId" : "SUBDEPT19", 
                "labServiceName" : "hello", 
                }
        ]
    }, 
    {
        "subDepartmentId" : "SUBDEPT21", 
        "subDepartmentName" : "Haemotology",
        "labServiceList" : [
            {
                "_id" : "456abc", 
                "subDepartmentId" : "SUBDEPT21", 
                "labServiceName" : "abcd", 
                }
        ]
    }
]

}

从上面的文档中,我只想使用它的 _id 值检索 labServiceList 的一个对象(例如:“_id”:本文档中的“123abc”)。除了匹配的嵌套文档之外,我不想获得任何其他字段。我尝试过以下查询:

db.labServiceMasters.aggregate([
{"$project": {
    "subDepartmentList": {"$filter": {
        "input": '$subDepartmentList.labServiceList',
        "as": 'labServiceList',
        "cond": {"$eq": ['$$labServiceList._id', '123abc']}
    }},
    "_id": 0
}}

])

我也尝试过使用 $map 运算符,但没有任何问题。请帮我解决这个问题。还请帮助我在 Java 中使用 mongoTemplate 编写相同的查询。任何建议都将是可观的。在此先感谢:-)

【问题讨论】:

    标签: java mongodb mongodb-query aggregation-framework spring-data-mongodb


    【解决方案1】:

    您实际上需要在$filter 内嵌套一个$map,在$map 内嵌套另一个$filter。并使用$arrayElemAt 获取单个条目:

    db.labServiceMasters.aggregate([
      { "$project": {
        "subDepartmentList": {
          "$arrayElemAt": [
            { "$filter": {
              "input": {
                "$map": {
                  "input": "$subDepartmentList",
                  "as": "sd",
                  "in": {
                    "$arrayElemAt": [
                      { "$filter": {
                        "input": "$$sd.labServiceList",
                        "as": "ls",
                        "cond": { "$eq": [ "$$ls._id", "123abc" ] }
                      }},
                      0
                    ]  
                  }
                }
              },
              "as": "sd",
              "cond": { "$ne": [ "$$sd", null ] }
            }},
            0
          ]
        }  
      }}
    ])
    

    返回:

    {
        "_id" : "PT5",
        "subDepartmentList" : {
            "_id" : "123abc",
            "subDepartmentId" : "SUBDEPT19",
            "labServiceName" : "serviceOne"
        }
    }
    

    spring-mongodb 是:

        Aggregation aggregation = newAggregation(
          project("subDepartmentList").and(new AggregationExpression() {
              @Override
              public DBObject toDbObject(AggregationOperationContext context) {
                  return new BasicDBObject(
                    "$arrayElemAt", Arrays.asList(
                      new BasicDBObject("$filter",
                        new BasicDBObject("input",
                          new BasicDBObject("$map",
                            new BasicDBObject("input","$subDepartmentList")
                              .append("as","sd")
                              .append("in",new BasicDBObject(
                                "$arrayElemAt", Arrays.asList(
                                  new BasicDBObject("$filter",
                                    new BasicDBObject("input","$$sd.labServiceList")
                                      .append("as","ls")
                                      .append("cond", new BasicDBObject("$eq", Arrays.asList("$$ls._id","123abc")))
                                  ),
                                  0
                                )
                              ))
                          )
                        )
                        .append("as","sd")
                        .append("$ne", Arrays.asList("$$sd", null))
                      ),
                      0
                    )
                  );
              }
          }).as("subDepartmentList")
        );
    

    和序列化一样:

    {
      "aggregate": "labServiceMasters",
      "pipeline": [
        {
          "$project": {
            "subDepartmentList": {
              "$arrayElemAt": [
                {
                  "$filter": {
                    "input": {
                      "$map": {
                        "input": "$subDepartmentList",
                        "as": "sd",
                        "in": {
                          "$arrayElemAt": [
                            {
                              "$filter": {
                                "input": "$$sd.labServiceList",
                                "as": "ls",
                                "cond": {
                                  "$eq": [
                                    "$$ls._id",
                                    "123abc"
                                  ]
                                }
                              }
                            },
                            0.0
                          ]
                        }
                      }
                    },
                    "as": "sd",
                    "$ne": [
                      "$$sd",
                      null
                    ]
                  }
                },
                0.0
              ]
            }
          }
        }
      ]
    }
    

    【讨论】:

    • wowww :-) 非常感谢 Neil :-) 你拯救了我的一天......这就是我想要的,我一整天都在努力实现这一目标。在您的回答中,我尝试过使用 shell 的查询并且非常好。我无法尝试 java 查询,稍后我将尝试执行相同的操作,我相信即使这样也可以 :-) 再次感谢大家 :-)
    • Neil 我尝试使用 Java 查询,但未能实现,因为它给出了一些编译错误,我尝试了所有方法,但没有任何效果。如果您可以跟踪错误,请帮助我。当我使用 Spring 时,如果 Java 查询是使用 mongoTemplate,那么它对我会更有帮助。谢谢:-)
    • @user3418760 这是从我的 IDE 中剪切和粘贴代码,所以它确实有效。如果你有问题,那是因为你自己打字。我建议您类似地从这里“复制”代码,只需使用它,直到您了解如何自己编写管道。还要检查您是否已将 sping-mongodb 更新到项目中的最新版本。
    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 2023-03-29
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2021-12-04
    相关资源
    最近更新 更多