Search code examples
springmongodbspring-dataprojection

Projection to child's field


Spring 1.3.6, using spring-data mongodb

Have a document like this:

{
  "name":"Dmitry",
  "props":{
    "city":"Moscow"
    "age":"26"
  }
}

Want something like this via spring mongo projection

{
  "city":"Moscow",
  "person":{
    "name":"Dmitry",
    "age":"26"
   }
}

Tried this aggregation operations

Aggregation aggregation = newAggregation(
    project().and("name").as("person.name")
        .and("props.city").as("city")
        .and("props.age").as("person.age")
);
AggregationResults<DBObject> results = this.mongoTemplate.aggregate(aggregation, MyType.class, DBObject.class);
results.getMappedResults();

Have a result like this

{
  "city":"Moscow",
  "name":"Dmitry",
  "person":{  
    "age":"26"
   }
}

It is ok to bind field as field with another name, to bind child field to parent field, to bind child field to another child, but I haven't succeed on binding parent field to child via mongo projection.


Solution

  • Here is the Spring code using projection. You may need to replace this code "getMongoConnection()" based on how you get MongoOperations object from Spring context.

    Aggregate method using projection:-

    public Boolean aggregateMyTypeCollectionUsingProject() {
    
            MongoOperations mongoOperations = getMongoConnection();
    
            ProjectionOperation  project = Aggregation.project().and("props.city").as("city").and("props.age").as("person.age").andExpression("name")
                    .as("person.name");
            Aggregation aggregate = Aggregation.newAggregation(project);
    
            System.out.println(aggregate.toString());
            AggregationResults<DBObject> results = mongoOperations.aggregate(aggregate, MyType.class, DBObject.class);
    
            System.out.println("Result ============>" + results.getMappedResults());
            return true;
    
        }
    

    My getMongoConnection() method:-

    @SuppressWarnings("resource")
    public MongoOperations getMongoConnection() {
    
        return (MongoOperations) new AnnotationConfigApplicationContext(SpringMongoConfig.class)
                .getBean("mongoTemplate");
    }
    

    Query:-

    { "aggregate" : "__collection__" , "pipeline" : [ { "$project" : { "city" : "$props.city" , "person.age" : "$props.age" , "person.name" : "$name"}}]}
    

    Output:-

    {
        "_id": {
            "$oid": "57b32d31ced49443e4b79f0d"
        },
        "city": "Moscow",
        "person": {
            "age": "26",
            "name": "Dmitry"
        }
    }