Corneliu Lungociu
Corneliu Lungociu

Reputation: 13

Spring data MongoDB Criteria for regex search in array

I want to search the documents that have specific values in an array field, using MongoOperations. The documents look like this:

{countries: ["UK", "US", "JP"]}
{countries: ["UK"]}

The query that I want to execute looks like this (it works ok when I run it from the cloud mongo ui):

{
countries: { $elemMatch: {$regex: "uk", $options: 'i'}},  
countries: { $elemMatch: {$regex: "Us", $options: 'i'}}
} 

The intent is to return the documents that have all the countries that are specified in the query, and to do the search case insensitive. So this query should return only the first document, because it contains both UK and US.

Note that the list of countries to search for (uk and us in this example) is received as a parameter, so I don't know in advanced how many countries will be in the list. This is why I was thinking to use Criteria api, but can't manage to create this query using this api.

Is there a way to do this?

Node: I managed to make it work using collations, (see solution below) but I wanted to avoid this, because I don't want to hardcode the locale. Code that works with collations:

Criteria.where("countries")
.all(countriesList);
.collation(Collation.of(Locale.US).strength(Collation.ComparisonLevel.secondary()););

Upvotes: 0

Views: 4414

Answers (3)

herman
herman

Reputation: 12305

To achieve the same results as the query in the question, meaning AND between the conditions, one can use the following:

var uk = Criteria.where("countries").regex("uk", "i");
var us = Criteria.where("countries").regex("us", "i");
var both = new Criteria().andOperator(uk, us);

Upvotes: 0

Corneliu Lungociu
Corneliu Lungociu

Reputation: 13

What I ended up doing is that instead of this query:

{
countries: { $elemMatch: {$regex: "uk", $options: 'i'}},  
countries: { $elemMatch: {$regex: "Us", $options: 'i'}}
} 

I run this one

{
    countries: { $regex: "uk|Us", $options: 'i'}
}

The second one can be build sipmly like this:

Criteria.where(key).regex(regex, "i");

The two are not perfectly identical. The first one does an AND but the second one does and OR between the conditions. For my scenario this is fine.

Upvotes: 1

RONAK SUTARIYA
RONAK SUTARIYA

Reputation: 544

you can try with this method for apply in regex in your Query

Criteria.where("countries").regex("A"));

Upvotes: 0

Related Questions