dmitryvim
dmitryvim

Reputation: 2043

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.

Upvotes: 0

Views: 1054

Answers (2)

notionquest
notionquest

Reputation: 39186

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

Upvotes: 1

Clement Amarnath
Clement Amarnath

Reputation: 5466

Print the generated aggregate query and see whether, it matches the below query.

db.stackoverflow.aggregate([{$project:{"person.name": "$name", city:"$props.city", "person.age":"$props.age"}}]).pretty();

When I execute the query, I got the below result

{
        "_id" : ObjectId("57b32a0fc516d5b5c94cae0d"),
        "person" : {
                "name" : "Dmitry",
                "age" : "26"
        },
        "city" : "Moscow"
}
{
        "_id" : ObjectId("57b32b59c516d5b5c94cae0e"),
        "person" : {
                "name" : "Roseline",
                "age" : "22"
        },
        "city" : "Berlin"
}

These are records in my collection

db.stackoverflow.find().pretty();
{
        "_id" : ObjectId("57b32a0fc516d5b5c94cae0d"),
        "name" : "Dmitry",
        "props" : {
                "city" : "Moscow",
                "age" : "26"
        }
}
{
        "_id" : ObjectId("57b32b59c516d5b5c94cae0e"),
        "name" : "Roseline",
        "props" : {
                "city" : "Berlin",
                "age" : "22"
        }
}

Hope it Helps!!

Upvotes: 0

Related Questions