简体   繁体   中英

Mongo query with multiple filters on same attribute doesn't work with JAVA

I'm new to mongoDb and created a query that fulfills my functional requirements:

db.collection.find( 
{
    "typeD": "ABC"
    , "typeT": {$size: 2}
    , "typeT": { $all: ["def", "abc"] }
    , "typeC": { $size: 3}
    , "typeC": { $all: ["pdf", "video", "png"] }
    , "properties": {$size: 3}
    ,"properties": 
    {
        $all: 
        [
          {"$elemMatch": {"name": "propName1", "value": "proName1_value"} } 
        , {"$elemMatch": {"name": "propName2", "value": "proName2_value"} } 
        , {"$elemMatch": {"name": "propName3", "value": "proName3_value"} } 
        ]
    }   
);

I want to find the documents that exactly contains the elements provided by the arrays - as a fixed order of the elements inside arrays cannot be assumed, I've chosen the $all operator and to ensure exact matching I added to additional restriction with the $size.

Above query can be executed on mongo shell without any problems.

While trying to execute this statement with java by using mongoTemplate, I get some problems:

BasicQuery query = new BasicQuery(queryString);
CollectionEntity existingCmc = this.mongoTemplate.find(query, CollectionEntity.class);

After the first java line, query.toString() provides:

db.collection.find( 
{
    "typeD": "ABC"
    , "typeT": { $all: ["def", "abc"] }
    , "typeC": { $all: ["pdf", "video", "png"] }
    ,"properties": 
    {
        $all: 
        [
          {"$elemMatch": {"name": "propName1", "value": "proName1_value"} } 
        , {"$elemMatch": {"name": "propName2", "value": "proName2_value"} } 
        , {"$elemMatch": {"name": "propName3", "value": "proName3_value"} } 
        ]
    }   
);

How can I execute the query that fulfills all of my requirements? Can I rewrite the query so that one "single condition per attribute" is in the query? How can I tell mongoTemplate, not to "overwrite" the previous condition for this attribute?

Thanks in advance

MongoDB queries are actually Maps (Key-Value pairs). Since you are defining 'properties' key two times which is why it is getting overridden. Your desired query can be done using '$and' operator.

{ "$and": [ 
    { "properties": { "$size": 3 } }, 
    { "properties": { $all: 
        [
            {"$elemMatch": {"name": "propName1", "value": "proName1_value"} }, 
            {"$elemMatch": {"name": "propName2", "value": "proName2_value"} },
            {"$elemMatch": {"name": "propName3", "value": "proName3_value"} } 
        ] 
   } } 
] }

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