代码之家  ›  专栏  ›  技术社区  ›  Anh Bui

Spring数据mongo中的Mongodb$lookup

  •  13
  • Anh Bui  · 技术社区  · 8 年前

    我是一个新的Mongodb,我在使用javaspring进行$lookup时遇到了问题。

    我想在Spring数据中使用这个shell

    db.NewFeed.aggregate([
        {
            $match : {username : "user001"}
        },
        {
          $lookup:
            {
              from: "NewfeedContent",
              localField: "content.contentId",
              foreignField: "_id",
              as: "NewfeedContent"
            }
       }
    ])
    

    我在谷歌上找到了,但还没有答案。

    5 回复  |  直到 6 年前
        1
  •  24
  •   Neo    5 年前

    使用Spring Data MongoDB连接两个集合

    员工类别

    class Employee {
        private String _id;
        private String name;
        private String dept_id;
    }
    

    部门班级

    class Department {
        private String _id;
        private String dept_name;
    }
    

    员工结果类

    public class EmpDeptResult {
    
        private String _id;
        private String name;
        private List<Object> departments;
    }
    

    员工服务类

    public class EmployeeService {
    
        @Autowired
        private MongoTemplate mongoTemplate;
    
        private Logger LOGGER = LoggerFactory.getLogger(EmployeeService.class);
    
        public void lookupOperation(){
        LookupOperation lookupOperation = LookupOperation.newLookup()
                            .from("Department")
                            .localField("dept_id")
                            .foreignField("_id")
                            .as("departments");
    
        Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("_id").is("1")) , lookupOperation);
            List<EmpDeptResult> results = mongoTemplate.aggregate(aggregation, "Employee", EmpDeptResult.class).getMappedResults();
            LOGGER.info("Obj Size " +results.size());
        }
    }
    
        2
  •  13
  •   Blakes Seven    8 年前

    并不是每一个“新”特性都能使其立即进入抽象层,例如 .

    因此,您只需要定义一个使用 AggregationOperation 接口,它将采用直接指定为其内容的BSON对象:

    public class CustomAggregationOperation implements AggregationOperation {
        private DBObject operation;
    
        public CustomAggregationOperation (DBObject operation) {
            this.operation = operation;
        }
    
        @Override
        public DBObject toDBObject(AggregationOperationContext context) {
            return context.getMappedObject(operation);
        }
    }
    

    然后,您可以在聚合中这样使用:

    Aggregation aggregation = newAggregation(
        match(
            Criteria.where("username").is("user001")
        ),
        new CustomAggregationOperation(
            new BasicDBObject(
                "$lookup",
                new BasicDBObject("from", "NewFeedContent")
                    .append("localField","content.contentId")
                    .append("foreignField", "_id")
                    .append("as", "NewFeedContent")
            )
        )
    )
    

    它显示了与内置的 match() 管道助手。

    在每个帮助器下面发生的所有事情都是它们序列化为BSON表示,例如 DBObject 无论如何所以这里的构造函数直接获取对象,并直接从 .toDBObject() ,这是接口上的标准方法,将在序列化管道内容时调用。

        3
  •  8
  •   VK321    7 年前

    下面是一个例子:

    收集 帖子

    {
    "_id" : ObjectId("5a198074ed31adaf5d79fe8a"),
    "title" : "Post 1",
    "authors" : [1, 2]
    },
    {
    "_id" : ObjectId("5a198074ed31adaf5d79fe8d"),
    "title" : "Post 2",
    "authors" : [2]
    }
    

    收集 用户

    {
    "_id" : ObjectId("5a18b483ed31ada08fd6ed82"),
    "userId" : 1,
    "name" : "Vinod Kumar"
    },
    {
    "_id" : ObjectId("5a18b483ed31ada08fd6ed83"),
    "userId" : 2,
    "name" : "Jim Hazel"
    },
    {
    "_id" : ObjectId("5a18b483ed31ada08fd6ed84"),
    "userId" : 3,
    "name" : "Alex Wong"
    }
    

    带有查找和匹配的Mongodb查询

    db.users.aggregate([
    {
      $lookup:
        {
          from: "users",
          localField: "userid",
          foreignField: "authors",
          as: "post"
        }
      },
      {
         $match: { "post": { $ne: [] } }
      }
    ]).pretty()
    

    Spring Mongoopration语法

    LookupOperation lookupOperation = LookupOperation.newLookup().
                from("posts").
                localField("userid").
                foreignField("authors").
                as("post");
    
    AggregationOperation match = Aggregation.match(Criteria.where("post").size(1));
    
    
    Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);
    
    List<BasicDBObject> results = mongoOperation.aggregate(aggregation, "users", BasicDBObject.class).getMappedResults();
    
        4
  •  8
  •   Vivek Singh    5 年前

    现在回答这个问题已经太晚了,但它可能会帮助其他面临同样问题的人。 如果您使用的是spring-boot-data-mongodb-2.0或更高版本,那么有一个简单的方法来实现它。

    AggregationOperation match = Aggregation.match(Criteria.where("username").is("user001")));
    AggregationOperation query = Aggregation.lookup("NewfeedContent", "content.contentId", "_id", "NewfeedContent");
    // If you want to unwind
    //AggregationOperation unwind = Aggregation.unwind("Patient");
    Aggregation agr = Aggregation.newAggregation(query, match, unwind);
    AggregationResults<Document> result = springTemplate.aggregate(agr, "CollectionName", Document.class);
    
        5
  •  0
  •   MartenCatcher Ng. Hau    5 年前

    可使用以下内容加入3个收藏

    MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
    
    DB db = mongoClient.getDB( "DBname" );
    
    BasicDBObject query = BasicDBObject.parse("{$match:{_id:61188}},\n" +
            "   {\n" +
            "     $lookup:\n" +
            "       {\n" +
            "         from: \"CustomerDetails\",\n" +
            "         localField: \"supplierId\",\n" +
            "         foreignField: \"supplierId\",\n" +
            "         as: \"newfield\"\n" +
            "       }\n" +
            "  }\n" +
            "  ,  {\n" +
            "     $lookup:\n" +
            "       {\n" +
            "         from: \"ItemDetails\",\n" +
            "         localField: \"supplierId\",\n" +
            "         foreignField: \"supplierId\",\n" +
            "         as: \"newfield\"\n" +
            "       }\n" +
            "  }");
    
    AggregationOutput dumps = db.getCollection("HeaderInfo").aggregate(query);
    
    System.out.println("result="+dumps.results());