Mongodb $lookup in Spring data mongo

后端 未结 5 1891
走了就别回头了
走了就别回头了 2020-12-31 12:32

I\'m a new Mongodb and I have a problem with $lookup with java spring.

I would like to use this shell in Spring data

db.NewFeed.aggregate([
    {
           


        
相关标签:
5条回答
  • Here is an example:

    Collection posts

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

    Collection users

    {
    "_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 query with lookup and match

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

    Spring Mongoopration syntax

    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();
    
    0 讨论(0)
  • 2020-12-31 12:56

    Can use below to join 3 Collections

    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());
    
    0 讨论(0)
  • 2020-12-31 13:01

    Its too late to answer this, but it might helps other who are facing the same issue. If you are using spring-boot-data-mongodb-2.0 or above version then there is a easy way to implement this.

    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);
    
    0 讨论(0)
  • 2020-12-31 13:03

    Not every "new" feature makes it immediately into abstraction layers such as spring-mongo.

    So instead, all you need do is define a class that uses the AggregationOperation interface, which will instead take a BSON Object specified directly as it's content:

    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);
        }
    }
    

    Then you can use in your aggregation like this:

    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")
            )
        )
    )
    

    Which shows the custom class mixed with the built in match() pipeline helper.

    All that happens underneath each helper is that they serialize to a BSON representation such as with DBObject anyway. So the constructor here just takes the object directly, and returns it directly from .toDBObject(), which is the standard method on the interface that will be called when serializing the pipline contents.

    0 讨论(0)
  • 2020-12-31 13:03

    Joining Two Collections with Spring Data MongoDB

    Employee Class

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

    Department Class

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

    Employee Result Class

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

    EmployeeService Class

    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());
        }
    }
    
    0 讨论(0)
提交回复
热议问题