Using mongo-java-driver to manipulate arrays - java

I'm using mongo-java-driver-2.11.2. I got stuck with array manipulation. I succeed in creating an array but failed with an exception of bad key: "$PUSH" while trying to insert an element into the array. Here is my code:
DBCursor cursor = iiCollection.find(new BasicDBObject(TOKEN, token.getToken()));
if(cursor.hasNext()){
DBObject o = cursor.next();
int freq = (Integer) o.get(FREQ);
iiCollection.update(o, new BasicDBObject(FREQ, freq + 1)
.append("$push", new BasicDBObject(DOCS, docId)));
}
else{
iiCollection.insert(new BasicDBObject(TOKEN, token.getToken())
.append(FREQ, 1)
.append(DOCS, new String[]{docId}));
}
The 'else' branch is ok, but the first branch won't work, please help me figure out the problem.

The following code should do the trick:
iiCollection.update(o, new BasicDBObject("$set",new BasicDBObject("freq", freq+1)).append("$push", new BasicDBObject("docs", 1)));
The reason for this is that when you execute the code like below,
new BasicDBObject("freq", freq+1).append("$push", new BasicDBObject("docs", 1))
it converts to
{ "freq" : 3 , "$push" : { "docs" : 1}}
which is incorrect.

Related

Why the aggregate function does not give the desired result?

Was trying to change the data type of all values in a specific field, without use of iterators.
Here tid is the field name
I tried running the code in Mongo using
var ch ={"$addFields" : { "tid" : { "$convert":{"input":"$tid" , "to" : 2}}}}
db.test.aggregate(ch);
Where test is my collection
Java Code :
BasicDBObject fieldObject = new BasicDBObject();
fieldObject.put("$convert",new BasicDBObject().append("input",
"$tid").append("to", 2));
BasicDBObject addField = new BasicDBObject("$addFields",new
BasicDBObject("tid",fieldObject));
System.out.println(addField);
List<BasicDBObject> options = new ArrayList<>();
options.add(addField);
details.aggregate(options);
When I ran the code in mongo command line, the data types are changing from Integer to String.
But no change when I run the same through java code. Is there any issue with my Java Code.

Nested Querying in mongodb datase

I am bit new to mongodb and also in java. I want to query the key breaktime and find the sum of the value.
db.users90.find().pretty()
{
"_id" : ObjectId("5ad5f2e2f58a542f7989e8fc"),
"date" : "2018-04-17",
"break" : [
{
"out" : "18:00",
"in" : "18:40",
"breaktime" : "0:40"
},
{
"out" : "19:00",
"in" : "19:30",
"breaktime" : "0:30"
}
]
}
I need a help in java, to add those 2 breaktime keys(some cases it may be n number of documents in break)
0:40+0:30 = 0:70 minutes
Thanks,
Mohan
Although the query you need is simple, having your "breaktime" values stored as String, makes everything difficult and complex for no reason.
So, assuming you have stored these values as numbers e.g. double, you could easily execute your query in Java like this;
AggregateIterable aggregationQuery = collection.aggregate(Arrays.asList(
new Document("$match", new Document("date","yourDate")), // match a document with a specific date
new Document("$unwind", "$break"), // decompose the 'break' array
new Document("$group", new Document("_id", null).
append("totalBreakTime", new Document("$sum","$break.breaktime"))
)));
if (aggregationQuery.iterator().hasNext()){
double totalBreakTime = ((Document)aggregationQuery.iterator().next()).get("break",Document.class).getDouble("breakTime");
}

Changefeed on one column RethinkDB

I want to have a changefeed on one attribute of my object in rethinkdb in the java language.
I tried this:
Cursor curs = r.db("mytestdb").
table("tennis").
get(Constants.WORKING_PROJECT_ID).
getField("time").
changes().
run(conn);
for (Object doc : curs) {
System.out.println(doc);
}
but I get this com.rethinkdb.gen.exc.ReqlQueryLogicError: Cannot convert STRING to SEQUENCE as an Exception.
Im really new to rethinkDB. Can someone help me ?
getField("time") gets particular field value, you can't subscribe on value.
That's what this com.rethinkdb.gen.exc.ReqlQueryLogicError: Cannot convert STRING to SEQUENCE says.
You can filter changes you want to get:
Cursor curs = r.db("mytestdb").
table("tennis").get(Constants.WORKING_PROJECT_ID)
.filter(row -> row.g("new_val").g("time").ne(row.g("old_val").g("time")))
.changes().run(conn);
for (Object doc : curs) {
}

mongoDB: cursor notimeout setting isn't working in java client

i set an 'notimeout' option to a dbcursor in java:
BasicDBObject nearbyQueries = new BasicDBObject("$gt", 0)
.append("$lte", 2);
DBCursor trueClassInstances = locationsCollection.find(new BasicDBObject("distanceFromHotel", nearbyQueries)).addOption(Bytes.QUERYOPTION_NOTIMEOUT).limit(100000);
double counter = 0;
int currentPresent = 0;
for (DBObject instance : trueClassInstances) {
...
}
even with this option i set, this exception is thrown:
Exception in thread "main" com.mongodb.MongoCursorNotFoundException: Query failed with error code -5 and error message 'Cursor 1876954464377 not found on server XXXXXX:27017' on server XXXXXXXX:27017
at com.mongodb.connection.GetMoreProtocol.receiveMessage(GetMoreProtocol.java:115)
at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:68)
at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:37)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:155)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:219)
at com.mongodb.connection.DefaultServerConnection.getMore(DefaultServerConnection.java:194)
at com.mongodb.operation.QueryBatchCursor.getMore(QueryBatchCursor.java:197)
at com.mongodb.operation.QueryBatchCursor.hasNext(QueryBatchCursor.java:93)
at com.mongodb.MongoBatchCursorAdapter.hasNext(MongoBatchCursorAdapter.java:46)
at com.mongodb.DBCursor.hasNext(DBCursor.java:152)
at locationExtraction.DistanceClassification.FeatureAnalyzer.main(FeatureAnalyzer.java:27)
FeatureAnalyzer.java:27 is the for loop line.
this problem appear in other project with similar setting...
what am i doing wrong? maybe my choice of 'for' loop instead of this kind of iteration can cause this strange behavior?
while(cursor.hasNext())
{
DBObject next = cursor.next();
}
Thanks
Looks like you are not able to process each batch within time limit. Try reducing batch size so that each batch could be consumed before time runs out. This should help.
cursor.addOption(com.mongodb.Bytes.QUERYOPTION_NOTIMEOUT).batchSize(100)
so the problem is solved.
this is very strange but there is a problem with using 'for' loop for iterating on cursor. so dont do it like i did it, use 'while' loop:
while(cursor.hasNext())
{
DBObject next = cursor.next();
}
before use cursor.hasNext() and cursor.next() to do business logical, just before you get the mongo cursor, invoke FindIterable object's noCursorTimeout(true) method. for example:
FindIterable<Document> findIterable = sentenceColl.find(condition);
// set no timeout
findIterable.noCursorTimeout(true);
MongoCursor<Document> mongoCursor = findIterable.iterator();
while (mongoCursor.hasNext()) {
mongoCursor.next();
}
try this:
Iterator<BasicDBObject> it = null;
it = coll.find("{"field": {$in:#}}", fieldList).with(
new QueryModifier() {
public void modify(DBCursor cursor) {
cursor.setOptions(Bytes.QUERYOPTION_NOTIMEOUT);
}
}
).as(BasicDBObject.class);

get some attributes from mongodb except one or two

I would like to get some information which is in a mongoDB except some attributes.
I tried it in cmd and it worked:
db.orders.find({name:"chabeee"},{_id:0, name:1, worksAt:1})
Then I get this result:
{ "name" : "chabeee", "worksAt" : "jobAtBp" }
{ "name" : "chabeee", "worksAt" : "jobAtRE" }
Its okay, but I want to get in a Java Program. How can I do that?
You have to create one additional BasicDBObject, which will be used for pointing out which exact keys to be fetched. And finally the DBCollection#find(DBObject ref, DBObject keys) method has to be invoked in order to pass the desired projection keys.
BasicDBObject query = new BasicDBObject("name", "chabeee");
BasicDBObject keys = new BasicDBObject();
keys.put("_id", 0);
keys.put("name", 1);
keys.put("worksAt", 1);
BasicDBCursor result = collection.find(query, keys);
Then you just have to iterate over the BasicDBCursor and verify the result.
while (cursor.hasNext()) {
System.out.println(cursor.next());
}

Categories