How to convert a $expr mongo shell query to mongoTemplate?

54 Views Asked by At

Following is my collection:

[
  {
    "_id": 1,
    "favorite": {
      "color": "red",
      "foods": {
        "fruits": "banana",
        "fastfood": [
          "burger",
          "sandwich"
        ]
      }
    }
  },
  {
    "_id": 2,
    "favorite": {
      "color": "green",
      "foods": {
        "noodles": "ramen",
        "fastfood": [
          "fries",
          "burger",
          "corn dog"
        ]
      }
    }
  },
  {
    "_id": 3,
    "favorite": {
      "color": "red",
      "foods": {
        "soup": "cream soup"
      }
    }
  }
]

I need to check fastfood item is Identical or not. To achieve this, I have the mongo shell query already.

db.collection.find({
  $expr: {
    $eq: [
      [
        "burger",
        "sandwich"
      ],
      "$favorite.foods.fastfood"
    ]
  }
})

But, I need this in mongoTemplate as I am using Spring Boot Application. I can not do it so far.

1

There are 1 best solutions below

0
J.F. On

I think the translation to MongoTemplate could be this one where you say to mongo "give me the elements where favorite.foods.fastfood is ["burger", "sandwich"].

Query query = new Query(Criteria.where("favorite.foods.fastfood").is(List.of("burger", "sandwich")));
return mongoTemplate.find(query, YourDesiredDocument.class);

But it will return data if the array is exactly the same including the elements order.

So for example array ["burger","sandwich"] will work fine.
But ["sandwich","burger"] will not return any data.

Maybe you don't need this but it can help, you can also try this query where order is noy checked, so all arrays with these elements will be returned.

Using MongoTemplate it can be something like this (not tested):

Query query = new Query(new Criteria().andOperator(
            Criteria.where("favorite.foods.fastfood").all("burger", "sandwich"),
            Criteria.where("favorite.foods.fastfood").size(2)
        ));
return mongoTemplate.find(query, YourDesiredDocument.class);