0

I have a mongodb query which works fine

db.user.aggregate([
  {
    "$project": {
      "data": {
        "$objectToArray": "$$ROOT"
      }
    }
  },
  {
    $unwind: "$data"
  },
  {
    "$match": {
      "data.v": {
        $regex: "Mohit Chandani"
      }
    }
  }
])

It basically, get all the document having the value Mohit Chandani and here is the output:

{ "_id" : "b387d728-1feb-45b6-bdec-dafdf22685e2", "data" : { "k" : "fullName", "v" : "Mohit Chandani" } }
{ "_id" : "8e35c497-4296-4ad9-8af6-9187dc0344f7", "data" : { "k" : "fullName", "v" : "Mohit Chandani" } }
{ "_id" : "c38b6767-6665-46b8-bd29-645c41d03850", "data" : { "k" : "fullName", "v" : "Mohit Chandani" } }

I need this query to be converted for my spring boot application and I am writing the following:-

Aggregation aggregation = Aggregation.newAggregation(Aggregation.project(Aggregation.ROOT), Aggregation.match(Criteria.where(connectionRequest.getWord())));

It would be helpful to know which approach to take when you do long aggregations in Spring-Data.

Mohit Chandani
  • 101
  • 1
  • 12
  • For what it’s worth, your aggregate query may work fine but I highly doubt it performs well because of the multiple pipelines for just a regex query on a field. Also $unwind pipeline stage tends to slow down operations a bit since there’s a bit of effort required to unfold all the documents in an array. – chridam Jan 15 '21 at 12:21
  • what you mean by "convert for my spring boot application"? – deadshot Jan 15 '21 at 12:23
  • @deadshot I need the query to be executed through the spring boot application and not from the mongodb shell. – Mohit Chandani Jan 15 '21 at 12:27
  • @chridam yes I get your point – Mohit Chandani Jan 15 '21 at 12:30
  • this will help https://stackoverflow.com/a/59726492/9050514 – deadshot Jan 15 '21 at 12:30
  • Does the answer help you? – varman Jan 16 '21 at 18:09
  • @varman The main issue is I don't know about any fields I have just database uri and I want to perform a search operation in all the databases and want the fields collection and database which contains that "string". Do you have any idea of how to return if there is no .class present of that collection name. – Mohit Chandani Jan 18 '21 at 07:22
  • So do you know the fileds that you need? – varman Jan 18 '21 at 07:26
  • @varman No I just have the databse uri `MongoIterable collections = database.listCollectionNames();` This is how I am getting the collection name present in the database – Mohit Chandani Jan 18 '21 at 07:41
  • I wonder, if you dont know the fields, how can you do aggregation? – varman Jan 18 '21 at 07:48

1 Answers1

2

This might help you, Hope you are using MongoTemplate for aggregation.

@Autowired
private MongoTemplate mongoTemplate;

And the code for above script is

public List<Object> test() {

    Aggregation.newAggregation(
        project().and(ObjectOperators.valueOf(ROOT).toArray()).as("data"),
        unwind("data"),
        match(Criteria.where("data.v").regex("Mohit Chandani")
        )
    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();

}

I'm not sure the project() of above code would work, because I haven't tried it. I referred it form Spring data mongodb

If it doesn't work, this would definitely work. Few opetaiotion are not suppored in spring data like $addFields, $filter.. So we do a Trick to convert

public List<Object> test() {

    Aggregation aggregation = Aggregation.newAggregation(
        
        p-> new Document("$project",
                new Document("data",
                    new Document("$objectToArray","$$ROOT")
                )     
            ),
        unwind("data"),
        match(Criteria.where("data.v").regex("Mohit Chandani"))     

    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();

}
varman
  • 8,704
  • 5
  • 19
  • 53