简体   繁体   中英

Filter the document if any value of the provided list is present in the document's array

Document

    {
    "status": {
            "active": [
                "A",
                "B"
            ],
            "inactive": [
                "C",
                "D"
            ]
        }
    }

Code

Criteria statusFilterCriteria = Criteria.getInstance(
   CriteriaType.ARRAY_CONTAINS,
   "status.active",   
   Collections.singletonList("A"), 
   Part.IgnoreCaseType.NEVER);
CosmosQuery cosmosQuery = new CosmosQuery(statusFilterCriteria);

The filtering criteria is that if any value of the list is present in the active array, then the Document should be returned. Since A is present in active array I get A in response. But when I pass A and B both in the list, I don't get the Document in my response.

You can only pass a single value because the ARRAY_CONTAINS function in Cosmos DB backend itself only supports searching for a single value in the json array (see documentation here ). I realise this is misleading in the context of Spring and Criteria.getInstance(), since this is expecting List<Object> values, so the natural assumption you made is that it will search for all the values in the list... but you can only pass one value.

To accomplish this, you will need to run the query each time for each value in the list. Something like the below snippet, which assumes there are multiple documents of this shape in your container, and collects all the docs that meet the filtering criteria into a HashMap.

Iterable<User> results = null;
String[] lettersArray = { "A", "B" };
HashMap<String, User> docMap = new HashMap<String, User>();
List<String> letters = Arrays.asList(lettersArray);
for (String object : letters) {
    Criteria statusFilterCriteria = Criteria.getInstance(
            CriteriaType.ARRAY_CONTAINS, "status.active", Collections.singletonList(object),
            Part.IgnoreCaseType.NEVER);
    CosmosQuery cosmosQuery = new CosmosQuery(statusFilterCriteria);
    results = cosmosTemplate.find(cosmosQuery, User.class, "myContainer5");
    for (User user : results)
        docMap.put(user.getId(), user);
}
List<String> docIds = new ArrayList<String>();
for (String id : docMap.keySet())
    docIds.add(id);
System.out.println("ids of docs that contain any of the letters: " + String.join(", ", docIds));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM