简体   繁体   中英

“or” condition in embedded document java

  1. What is the correct syntax for creating $or condition in embedded document in MongoDB Java driver?

  2. Is it actually possible to get a cursor to embedded documents?

Suppose I have the following document:

{
    statuses: [{
        {
            streamName: A
        }{
            statusA: 0
        }{
            statusB: 1
        }
    },
    {
        {
            streamName: B
        }{
            statusA: 0
        }{
            statusB: 1
        }
    }]
}

I would also like to get cursor to sub documents (in array of statuses) that has at least one status bigger than 0.

This is how I did it but it didn't work:

List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
DBObject query = new BasicDBObject();

obj.add(new BasicDBObject ("statuses", 
        new BasicDBObject ("statusA",
        new BasicDBObject ("$gt",0 ) )));

obj.add(new BasicDBObject ("statuses",
        new BasicDBObject ("statusB" ,
        new BasicDBObject ("$gt",0 ) )));

query.put("$or",obj)
db.find(collectionName,query)

I didn't find any documentation on that.

What you have translates to

{ "$or" : [ { "statuses" : { "statusA" : { "$gt" : 0}}} , { "statuses" : { "statusB" : { "$gt" : 0}}}]}

which is used for whole document comparison.

For comparing fields inside an embedded arrays/doc you've to use dot notation.

{ "$or" : [ { "statuses.statusA" : { "$gt" : 0}} , { "statuses.statusB" : { "$gt" : 0}}]}

The equliavent java code is below

List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
DBObject query = new BasicDBObject();
obj.add(new BasicDBObject ("statuses.statusA", new BasicDBObject ("$gt",0 ) ));
obj.add(new BasicDBObject ("statuses.statusB" , new BasicDBObject ("$gt",0 ) ));
query.put("$or",obj);

Alternatively you can use $elemMatch to run matches on embedded arrays. Similar to what you've but $elemMatch applies condition to each fields.

Something like

{ "statuses" : { "$elemMatch" : { "$or" : [ { "statusA" : { "$gt" : 0}} , { "statusB" : { "$gt" : 0}}]}}}

Java Code

BasicDBList obj = new BasicDBList();
obj.add(new BasicDBObject ("statusA",new BasicDBObject ("$gt",0 ) ));
obj.add(new BasicDBObject ("statusB",new BasicDBObject ("$gt",0 ) ));
DBObject query = new BasicDBObject("statuses", new BasicDBObject("$elemMatch", new BasicDBObject("$or",obj)));

Count the no of matching occurrences.

Bson count = new Document("statuses", Document.parse("{$size:{\n" +
            "            $filter: {\n" +
            "               input: \"$statuses\",\n" +
            "               as: \"status\",\n" +
            "               cond: { \"$or\" : [ {$gt:[\"$$status.statusA\", 0]} , {$gt:[\"$$status.statusB\", 0]}]}\n" +
            "            }\n" +
            "         }}"));
Bson project = new Document("$project", count);
col.aggregate(Arrays.asList(project));

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