简体   繁体   English

带有 mongoTemplate 的 DbRef 字段的 Mongo 聚合

[英]Mongo aggregation for a DbRef field with mongoTemplate

Assume I have two mongo collections as follows.假设我有两个 mongo 集合,如下所示。

Collection A
{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e0"),
    "level" : "super"
    "dataReference" : Object
        B : DbRef(B, 5b618a570550de0021aaa2ef, undefined)
}

Collection B
{ 
    "_id" : ObjectId("5b618a570550de0021aaa2ef"),  
    "role" : "admin"
}

What I need is retrieve the records from Collection A, which records have "level" field's value as "super" and its related Collection B record's "role" value as "admin".我需要的是从集合 A 中检索记录,这些记录的“级别”字段值为“超级”,其相关集合 B 记录的“角色”值为“管理员”。

For this, I am trying to use aggregation and java mongoTemplate.为此,我正在尝试使用聚合和 java mongoTemplate。

Following is the code that I tried but it returns 0 records.以下是我尝试过的代码,但它返回 0 条记录。

final TypedAggregation<A> typedAggregation = Aggregation.newAggregation(A.class,
                Aggregation.match(Criteria.where("level").equals(level)),
                Aggregation.lookup("B", "_id", "dataReference.B.$id", "Basb"),
                Aggregation.match(new Criteria().andOperator(
                        Criteria.where("B.role").regex("admin")
                )));

        final AggregationResults<Map> A = mongoTemplate.aggregate(typedAggregation, "A", Map.class);

Please note that I am new to Mongo aggregation.请注意,我是 Mongo 聚合的新手。

It's quiet ugly solution:这是安静丑陋的解决方案:

MongoTemplate蒙戈模板

You cannot use TypedAggregation because we need to transform A collection to be able join with B collection您不能使用TypedAggregation因为我们需要转换A集合才能加入B集合

Aggregation typedAggregation = Aggregation.newAggregation(
    Aggregation.match(Criteria.where("level").is("super")),
    new AggregationOperation() {
        @Override
        public Document toDocument(AggregationOperationContext context) {
            return Document.parse("{\"$addFields\":{\"dataReference\":{\"$reduce\":{\"input\":{\"$objectToArray\":\"$dataReference\"},\"initialValue\":null,\"in\":{\"$cond\":[{\"$eq\":[{\"$type\":\"$$this.v\"},\"objectId\"]},\"$$this.v\",\"$$value\"]}}}}}");
        }
    },
    Aggregation.lookup("B", "dataReference", "_id", "B"),
    Aggregation.match(new Criteria().andOperator(
             Criteria.where("B.role").regex("admin")
        )
    )
);

final AggregationResults<Document> A = mongoTemplate.aggregate(typedAggregation, "A", Document.class);

MongoDB Aggregation MongoDB 聚合

db.A.aggregate([
  {
    "$match": {
      "level": "super"
    }
  },
  {
    "$addFields": {
      "B": {
        "$reduce": {
          "input": {
            "$objectToArray": "$dataReference"
          },
          "initialValue": null,
          "in": {
            "$cond": [
              {
                "$eq": [
                  {
                    "$type": "$$this.v"
                  },
                  "objectId"
                ]
              },
              "$$this.v",
              "$$value"
            ]
          }
        }
      }
    }
  },
  {
    "$lookup": {
      "from": "B",
      "localField": "B",
      "foreignField": "_id",
      "as": "B"
    }
  },
  {
    "$match": {
      "$and": [
        {
          "B.role": {
            "$regex": "admin",
            "$options": ""
          }
        }
      ]
    }
  }
])

MongoPlayground蒙戈游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM