Mongo DB regex aggregation query using java API - mongodb

I want to query using regex and aggregation in mongo db, the following is working fine in mongo shell but how to write the same using Java API.
db.posts_collection.aggregate({$unwind:"$posts"},
{$match :{"posts.message":/.*keyword.*/} })
I tried using the following but unable to get the required result,
BasicDBObject unwind = new BasicDBObject("$unwind","$posts");
BasicDBObject matchKeyWord = new BasicDBObject("$match",new
BasicDBObject("posts.message",java.util.regex.Pattern.compile("keyword")));
AggregationOutput output = collection.aggregate(unwind,matchKeyWord);
Please tell me how to write the same query in java.

I would think that should work, but if you really wanted to be sure use the $regex operator form instead:
BasicDBObject unwind = new BasicDBObject("$unwind","$posts");
BasicDBObject matchKeyWord = new BasicDBObject(
"$match",new BasicDBObject(
"posts.message",new BasicDBObject("$regex",".*keyword.*")
)
);
AggregationOutput output = collection.aggregate(unwind,matchKeyWord);
That operator exists for the purpose of "safe" serialization with differing drivers.

Related

mongo group with match query does not work with java

I have below query working in robo 3T console.
db.metrics.aggregate([
{'$match':{'status':'SUCCESS'}},
{'$group':{ _id:'$bapiName',count:{$sum:1}}}
])
But when I execute it with java,
MongoCollection collection =db.getCollection();
List<Bson> pipeLine = new ArrayList<Bson>();
pipeLine.add(Document.parse("{'$match':{'status':'SUCCESS'}}"));
pipeLine.add(Document.parse("{'$group' : {_id: {bapiName:'$bapiName',status:'$status'}, count:{$sum:1}}}"));
Iterator iterator = collection.aggregate(query.getPipeline()).iterator();
while( iterator.hasNext()) {
Object object = iterator.next();
resultList.add((Document)object);
System.out.println(" class "+object.getClass()+" data "+object);
}
I am not getting the results. Iterator is empty. Any changes need to be made in java to get it working?

Morphia Aggregation Pipeliene

I need a little help with an aggregation pipeline in morphia. This is what I have in mongo:
db.transacciones.aggregate([
{$match:
{"$and":[
{"usuario._id": "xxx#gmail.com"},
{"status":{"$ne":"ERROR"}}]}},
{$sort:{"date": -1}},
{$group:{"ordenId", "transaction" : {$first:"$$ROOT"}}},
{$replaceRoot:{newRoot:"$transaction"}}])
Ok, this is what I have in morphia:
Query<TransaccionP2P> match = ds.getQueryFactory().createQuery(ds);
match.and(match.criteria("usuario._id").equal(usuarioId),
match.criteria("status").notEqual(Status.ST_ERROR));
Sort sort = Sort.descending("date");
Group group = grouping("transaction", Accumulator.accumulator("$first", (Object)"$$ROOT"));
Projection[] projections = {
Projection.projection("_id", "$transaction._id"),
...
};
AggregationPipeline pipeline = ds.createAggregation(TransaccionP2P.class)
.match(match)
.sort(sort)
.group("orden._id", group)
.project(projections);
Iterator<TransaccionP2P> iterator = pipeline.aggregate(TransaccionP2P.class);
List<TransaccionP2P> transacciones = new ArrayList<>();
iterator.forEachRemaining(transacciones::add);
I have managed to construct this pipeline with the stackoverflow articles I found because I couldn't find a good example in Morphia documentation but I have these problems:
Morphia doesn't seem to have support for $replaceRoot so I have to create the projection field by field.
The transaction variable in the group aggregate is not recognized in the projection step.
Here is the projection exception:
com.mongodb.MongoCommandException: Command failed with error 17276: 'Use of undefined variable: transaction'.
I haven't managed to find the correct way of making the projection for 'transaction' to be recognized.
Can you help me?
Thanks

Mongo DB : Implementing $not query

I am trying to implement following query from java code:
{ "Post Text" : { "$not" : /.*golf.*/i}}
my java code:
BasicDBObject not = new BasicDBObject();
not.append("$not", "/.*golf.*/i");
BasicDBObject query = new BasicDBObject();
query.put("Post Text", not);
When I am running above query, getting this log:
Cursor id=0, ns=journaldev.Rotunda, query={ "Post Text" : { "$not" : "/.golf./i" }}, numIterated=0, readPreference=primary
extra quotes around the regular expression are creating problem. Can someone help me in fixing this?
Using 3.x, you can use the Filters utility class to create various queries for you. In your case, you need the following construct:
Bson myFilter = Filters.not(
Filters.eq("Post Text",
Pattern.compile(".*golf.*", Pattern.CASE_INSENSITIVE)));
Using the 3.x driver to execute such a query is along the lines of:
MongoClient mongoClient = new MongoClient();
MongoCollection<Document> coll = mongoClient.getDatabase("test").getCollection("mycoll");
coll.find(myFilter); // do something with the FindIterable returned here
You can try something like this
Pattern textRegex = Pattern.compile(".*golf.*", Pattern.CASE_INSENSITIVE);
BasicDBObject not = new BasicDBObject("$not", textRegex);
BasicDBObject query = new BasicDBObject("Post Text", not);
When you pass a pattern, mongo driver automatically takes care of making it a regex. If you debug and see the code it will run with "$regex".
Hope this solves the problem

When does MongoDB Fetch results in java driver

MongoClient mc=new MongoClient();
MongoDatabase mdb=mc.getDatabase("testdb");
MongoCollection mcol=mdb.getCollection("testcol");
FindIterable<Document> fi=mcol.find();
MongoCursor<Document> mcur=fi.iterator();
MongoCursor<Document> mcur2=fi.iterator();
will mcur and mcur2 have same results all the time as they are reference of FindIterable fi.
In which step of the above code mongodb will get the results Inside mongoCursor or FindIterable step?
mcol.find() is the point where the results are obtained, the .find() will pull all documents from the collection "testcol".
You don't necessarily need to use a FindIterable object an ordinary List<BasicDBObject> does work.
then you can iterate through using:
for(DBObject obj : objList) {
//perform operations
String name = (String) obj.get("nameOfField");
}
hope this helps.

mongodb java to insert embedded document

I have a collection with embedded documents in it.
System
{
System_Info: ...,
Tenant: [
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
},
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
} ]
}
If I need to insert another tenant information like this
Tenant { Tenant_Id:2,Tenant_Info:"check",prop_info:"client"}.
whats the mongodb query to insert embedded documents? and how to do it using java?
Use the following code to insert into array :
BasicDBObject query = new BasicDBObject();
query.put( "System_Info", "...." );
BasicDBObject tenant = new BasicDBObject();
tenant.put("Tenant_Id", 2);
tenant.put("Tenant_Info", "check");
tenant.put("Prop_Info", "client");
BasicDBObject update = new BasicDBObject();
update.put("$push", new BasicDBObject("Tenant",tenant));
coll.update(query, update,true,true);
Are you trying to add another Tenant into the array? If so, you would want to create a DBObject representing the Tenant, and then $push it onto the array.
In Java, embedded documents are represented by DBObjects (of which BasicDBObject is a subclass). Here is an example of inserting an embedded document, from the docs:
http://www.mongodb.org/display/DOCS/Java+Tutorial#JavaTutorial-InsertingaDocument
Additionally, here is an example of using $push in Java:
Updating an array in MongoDB using Java driver
...and this is how to do it with mongo-driver version >= 3.1 (mine is 3.2.2):
Document tenant = new Document("Tenant_Id", 2)
.append("Tenant_Info", "check")
.append("Prop_Info", "client");
Bson filter = Filters.eq( "System_Info", "...." ); //get the parent-document
Bson setUpdate = Updates.push("Tenant", tenant);
coll.updateOne(filter, setUpdate);
Hope that helps someone.