简体   繁体   中英

MongoDB: Querying for subdocuments: Java

Writing a mongoDB 'query and update' in Java.

The mongoDB Collection(Name: reduced) result(map-reduce result) looks like below:

Value Field:

{ "value" : 

    { 
        "User_Name" : "Mitchamoreagent",
        "tweets" : ["RT    Perspectives:
        Texas Insurer of Last Resort Charts Course Through Reform Law", "RT  Texas sale
        s tax-free weekend set for Aug. 19-21", "RT  The New Normal: Billion-Dollar", "R
        T  Austin Water is responding to a 12-inch water main leak at Burnet Rd. and And
        erson Lane in North Austin."] 
    }
}

Trying to find all the the User_Name's whose tweets contain a 'word' which I can specify using regex.

To achieve this I tried AggregationOutput which works fine with simple cases. But this structure, I am not able to get through it.

Code:

 DBObject match = new BasicDBObject("$match",new BasicDBObject("value",new    BasicDBObject("tweets", new BasicDBObject("$regex",".*Texas.*"))));
 DBObject fields = new BasicDBObject("_id", 0); 
 DBObject nest = new BasicDBObject("value", new BasicDBObject("User_ID", 1));
 fields.put("value", 1);
 DBObject project = new BasicDBObject("$project", fields );
 AggregationOutput output = tweets.aggregate( match, project);

Here 'Texas' is the word I am trying to find, and I expect the output [Mitchamoreagent].

But the output is always an exception noRowsReturned.

You need to construct your $match stage operation as below:

 DBObject regex = new BasicDBObject("$regex","Texas");
 DBObject condition = new BasicDBObject("value.tweets",regex);
 DBObject match = new BasicDBObject("$match",condition);

The corresponding mongodb query that would be generated as in your question would be:

{$match:{"value":{"tweets":{$regex:"Texas"}}}}

which actually should be formed as:

{$match:{"value.tweets":{$regex:"Texas"}}}

The project stage should be built as below:

When you need to project a nested field's value as a top level field, in this case User_name , you need to project it using aliases, in this case the alias being user_name .

 DBObject fields = new BasicDBObject("_id", 0); 
 fields.put("user_name", "$value.User_Name"); // project the user_name for each record.

Execute the pipeline:

 DBObject project = new BasicDBObject("$project", fields );
 AggregationOutput output = tweets.aggregate( match, 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