6


I recently started exploring Aggregation Framework in MongoDB with SpringData. I could Create following query i.e

db.consumer_order.aggregate([
                            { $match: {_id: ObjectId("59e43f542397a00de0c688e4"), "orderState":"Confirmed"}},
                            { $project: {
                                parts: {$filter: {
                                    input: '$parts',
                                    as: 'item',
                                    cond: {$eq: ['$$item.currentState', "Estimation Confirmed"]}
                                }}
                            }}
                        ])

with MongoDB Native Driver in Spring with the following Code

List<Document> aggrigationList = new ArrayList<>();

List<String> conditions = new ArrayList<>();
conditions.add("$$item.currentState");
conditions.add("Estimation Confirmed");

Document matchDoc = new Document("$match",new Document("_id",new ObjectId(orderId)));
Document projectDoc = new Document("$project",new Document("parts",new Document("$filter",new Document("input","$parts").append("as", "item").append("cond", new Document("$eq",conditions)))));
aggrigationList.add(matchDoc);
aggrigationList.add(projectDoc);

Document orderWithPendingParts = consumerOrderCollection.aggregate(aggrigationList).first();

But I do know it's not a good practice to work always with Native Driver since we've Spring-Data in hand. But I'm having trouble to construct the above MongoDB query to AggrigationObject Using Spring Data. I tried with the below, But find difficulty in Constructing Aggregation.project() i.e

mongoTemplate.aggregate(Aggregation.newAggregation(
            Aggregation.match(Criteria.where("owner").is(user).andOperator(Criteria.where("orderState").is("confirmed"))),
            ***Finding Difficulty in here***
            ), inputType, outputType)

Guide me, If I'm doing something wrong.

s7vr
  • 73,656
  • 11
  • 106
  • 127
Kishore Kumar Korada
  • 1,204
  • 6
  • 22
  • 47

1 Answers1

18

You can try below query.

Static Imports

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter;
import static org.springframework.data.mongodb.core.aggregation.ComparisonOperators.Eq.valueOf;

Code

Aggregation aggregation = newAggregation(
           project().and(filter("parts")
             .as("item")
             .by(valueOf(
                  "item.currentState")
                   .equalToValue(
                  "Estimation Confirmed")))
          .as("parts");
);

List<outputType> results = mongoTemplate.aggregate(aggregation, inputType, outputType)
s7vr
  • 73,656
  • 11
  • 106
  • 127
  • Getting error since project method takes array of strings as parameters like project(String... fields), but you've specified Array Operators as parameters. Or Did I miss something – Kishore Kumar Korada Oct 17 '17 at 01:15
  • Thank you. I've tried it. It's working without errors. But when it comes to fetching results it's slightly different, when I'm expecting one document as a result, it's fetching multiple. Are you sure It matches exactly with above query I've mentioned? Because the query I've mentioned is what to be aggregated in spring. Thank you one more time for your patience :) – Kishore Kumar Korada Oct 17 '17 at 05:19
  • Np. This is the generated query `[ { "$project" : { "parts" : { "$filter" : { "input" : "$parts" , "as" : "item" , "cond" : { "$eq" : [ "$$item.currentState" , "Estimation Confirmed"]}}}}}]`. Are you sure your match is working correctly ? – s7vr Oct 17 '17 at 07:50
  • Can you add a document each which is expected and one which is not expected along with your updated query to the post ? – s7vr Oct 17 '17 at 12:42
  • Sure. Sorry for the late. I was on leave. – Kishore Kumar Korada Oct 25 '17 at 10:57
  • Oops!! my bad. My Match query is wrong. Your answer worked absolutely perfect :) Thank you. – Kishore Kumar Korada Oct 25 '17 at 11:44
  • Any idea how can i use **regex** inside ``equalToValue("Estimation Confirmed")``. Like if i give **est**. it should return the related data. @SagarVeeram – M N May 11 '20 at 18:48
  • Any idea how I can use an in clause instead of equalTo? – saran3h Nov 17 '21 at 14:28