Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement addFields mongoDB query in Java

I have found several example at StackOverFlow related to addFields in Aggregation. But no one implemented in Java.

db.getCollection('myDocument').aggregate([
    {$match : {"metaId.ref.uuid" : "d6112808-1ce1-4545-bd52-cf55bc4ed25e"}},
    {$lookup: {from: "simple", localField: "someId.ref.uuid", foreignField: "uuid", 
    as: "simple"}},
    {"$unwind": "$simple"},
    {"$addFields": { "metaId.ref.name" : "$simple.name" }}
])

I am not able to Implement In Java Correctly:-- Not getting proper procedure

   LookupOperation lookupOperation =LookupOperation.newLookup().from("simple").localField("execId.ref.uuid").foreignField("uuid").as("simple");
            Aggregation myDocAggr = newAggregation(match(Criteria.where("metaId.ref.uuid").is(someUUID)), group("uuid").max("version").as("version"),
                    lookupOperation,
                    Aggregates.unwind(""),
                Aggregates.addFields(fields));
            Document document =new Document();
            AggregationResults<String> myDocAggrResults = mongoTemplate.aggregate(myDocAggr , myDocument, myDocument.class);
            List<String> mydocumentList = myDocAggrResults .getMappedResults();

Not able to use unwind and addFields, this is sample java code, but it is not ok. Please help me. Thanks in advance

like image 391
Sheel Avatar asked Nov 12 '18 11:11

Sheel


3 Answers

You are mixing the java driver Aggregates method with Spring Aggregation methods.

Also $addFields is still not supported in spring mongo.

You have to use below aggregation.

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
Aggregation myDocAggr = newAggregation(
       match(Criteria.where("metaId.ref.uuid").is(someUUID)), 
       group("uuid").max("version").as("version"),
       lookup("simple","execId.ref.uuid","uuid","simple"),
       unwind("simple"),
       new AggregationOperation(){ 
         @Override 
         public Document toDocument(AggregationOperationContext aoc) {
            return new Document("$addFields",new Document("metaId.ref.name","$simple.name"));
         }
      }
)
List<Document> mydocumentList=mongoTemplate.aggregate(myDocAggr,"myDocument",Document.class).getMappedResults();
like image 108
s7vr Avatar answered Oct 18 '22 23:10

s7vr


Although the $addFields are not supported by spring mongo you can implement it by yourself:

import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.*;
import java.util.LinkedHashMap;
import java.util.Map;

public class AddFieldsOperation implements FieldsExposingAggregationOperation {
    private Map<String, Object> fields = new LinkedHashMap<>();

    public AddFieldsOperation(String field, AggregationExpression expression) {
        addField(field, expression);
    }

    public AddFieldsOperation addField(String field, AggregationExpression expression) {
        this.fields.put(field, expression.toDocument(Aggregation.DEFAULT_CONTEXT));
        return this;
    }

    @Override
    public Document toDocument(AggregationOperationContext context) {
        Document doc = new Document();
        fields.forEach(doc::append);
        return new Document("$addFields", doc);
    }

    @Override
    public boolean inheritsFields() {
        return true;
    }

    @Override
    public ExposedFields getFields() {
        final String[] fieldsArray = fields.keySet().toArray(new String[0]);
        return ExposedFields.synthetic(Fields.fields(fieldsArray));
    }

And use it like this:

...
ArithmeticOperators.Add value1 = ArithmeticOperators.Add.valueOf(0);
ArithmeticOperators.Add value2 = ArithmeticOperators.Add.valueOf(0);
AddFieldsOperation addFields
            = new AddFieldsOperation("value1", value1)
            .addField("value2", value2);
pipeline.add(addFields);
...
Add value1PlusValue2 = Add.valueOf("$value1").add("$value2");
...

Hope it will help someone.

like image 24
Vadim Zin4uk Avatar answered Oct 18 '22 23:10

Vadim Zin4uk


Since version 3.0 of 'spring-data-mongodb' it is actually possible to create a AddField aggration very easily. You can use the AddFieldsOperationBuilder.

In the example below I add a string id field for the objectId field named _id. The string field idString can get used in a lookup aggregation.

Example:

    AddFieldsOperation addFieldsOperation = Aggregation.addFields().addFieldWithValue("idString", ConvertOperators.ToString.toString("$_id")).build();
like image 4
user2255297 Avatar answered Oct 18 '22 23:10

user2255297