Resolving MongoDB error - java

public List<DBObject> findByDateDescending(int limit) {
List<BasicDBObject> posts = null;
// XXX HW 3.2, Work Here
// Return a list of DBObjects, each one a post from the posts collection
BasicDBObject query = new BasicDBObject();
BasicDBObject sortPredicate = new BasicDBObject();
sortPredicate.put("date", -1);
DBCursor cur = postsCollection.find(query).sort(sortPredicate);
int i = 0;
while( cur.hasNext() && i < limit ) {
if ( posts == null)
posts = new ArrayList<BasicDBObject>();
DBObject obj = cur.next();
posts.add(obj);
System.out.println("findByDateDescending(" + limit + " blog entry " + obj);
i++;
}
return posts;
}
I am getting an error at the posts and obj and the error is:
add(com.mongodb.BasicDBObject)List cannot be applied to com.mongodb.DBObject.
Can anyone help me with this?

You're trying to assign DBObject to BasicDBObject. Basically assigning a generic type to specific type. This is not allowed. Change your list to be List<DBObject> or obj to be BasicDBObject

Related

How to combine $in and max in MongoDb?

I want to get max timestamp of a set of tags from MongoDb history database. Say the tag ids are 1,2,3,4,5 I want to check all records for these tags and get the timestamp of latest. My collection looks like this along with data:
My code is as follows:
protected Timestamp getMaxRealTimeHistoryTimestamp(List<Integer> tagIds)
{
try
{
MongoClient mongo = new MongoClient(m_connectionInfo.getHost(), m_connectionInfo.getPort());
//Connecting to the database
MongoDatabase database = mongo.getDatabase(m_connectionInfo.getDatabaseName());
BasicDBObject andQuery = new BasicDBObject();
List<BasicDBObject> obj = new ArrayList<>();
obj.add(new BasicDBObject("TAG_ID", new BasicDBObject("$in", tagIds)));
MongoCollection<Document> collection = database.getCollection("EM_HISTORY");
Document doc = collection.find(andQuery).sort(new Document("TIME_STAMP", -1)).first();
if(doc != null)
{
return new Timestamp(((Date) doc.get("TIME_STAMP")).getTime());
}
}
catch (Exception e)
{
if (Logger.isErrorEnabled())
Logger.error(e);
}
return null;
}
the doc variable has some strange row that is not even in the collection
What am I doing wrong here?
BasicDBObject andQuery = new BasicDBObject();
List<BasicDBObject> obj = new ArrayList<>();
obj.add(new BasicDBObject("TAG_ID", new BasicDBObject("$in", tagIds)));
You are never adding the query filters from obj back into your andQuery, so the code ends up querying the collection without any filter.

What is the correct and efficient way for outputting json from MongoDB collections?

below you'll see a sample related with my style of serving of a mongodb collection data, it works but I've just concatenated the strings which is no good and thus it does not seem correct to me, I've checked for it on the net but could not see anything, if anyone knows please share with me.
#Path("/getdata/{collectionName}/{count}")
#GET
#Produces(MediaType.APPLICATION_JSON)
public String getData(#PathParam("collectionName") String collectionName, #PathParam("count") int count) throws UnknownHostException{
DB db = (new MongoClient("localhost")).getDB("testdb");
DBCollection dbCollection = db.getCollection(collectionName);
BasicDBObject basicDBObject = new BasicDBObject();
basicDBObject.put("name", "mustafa");
DBCursor dbCursor = dbCollection.find(basicDBObject);
String result = "{\" "+ collectionName +" \": [";
int i = 0;
while(dbCursor.hasNext() && i < count){
result += dbCursor.next() + ", ";
i++;
}
result = result.substring(0,result.length()-2);
result += "]}";
return result;
}
You can use com.mongodb.util.JSON.serialize() method to serialize your objects to JSON and return back.

How to implement $group aggregate code in mongo java

I want to use mongo aggregate in Java, but I cannot define $group code as:
In javascript:
$group = {
'_id':null,
'money_bank':{
'$sum':{
'$cond':[{'$eq'=>{'$type':'bank'}},'$amount',0]
}
}
In java:
BasicDBList eqList = new BasicDBList();
eqList.add("$type");
eqList.add("bank");
DBObject eqObject = BasicDBObjectBuilder.start().add("$eq", eqList).get();
BasicDBList condList = new BasicDBList();
condList.add(eqObject);
condList.add("$amount");
condList.add(0);
DBObject conObj = BasicDBObjectBuilder.start().add("$cond", condList).get();
DBObject sumObj = BasicDBObjectBuilder.start().add("$sum", conObj).get();
DBObject moneyObj = BasicDBObjectBuilder.start().add("money_bank", sumObj).get();
DBObject idObj = BasicDBObjectBuilder.start().add("_id", null).get();
BasicDBList groupList = new BasicDBList();
groupList.add(idObj);
groupList.add(moneyObj);
DBObject group = new BasicDBObject("$group", groupList);
But when I executed code, the error:
"errmsg" : "exception: a group's fields must be specified in an object"
Please help me in Java.
You've slightly misunderstood the correct way to turn this into a Java call, two of the places you've used a BasicDBList you actually needed to use a BasicDBObject instead - that's what that error means, it means you need to use an object not a list.
I've made the change to your code, but I haven't tested it against MongoDB, I leave that up to you.
The minimal changes needed to give you the equivalent of the Javascript is:
BasicDBObject eqArgs = new BasicDBObject("$type", "bank");
DBObject eqObject = BasicDBObjectBuilder.start().add("$eq", eqArgs).get();
BasicDBList condList = new BasicDBList();
condList.add(eqObject);
condList.add("$amount");
condList.add(0);
DBObject conObj = BasicDBObjectBuilder.start().add("$cond", condList).get();
DBObject sumObj = BasicDBObjectBuilder.start().add("$sum", conObj).get();
BasicDBObject groupArgs = new BasicDBObject();
groupArgs.append("_id", null);
groupArgs.append("money_bank", sumObj);
DBObject group = new BasicDBObject("$group", groupArgs);
// Using an assert to check it's correct, remove in production code
Assert.assertThat(group.toString(), is("{ \"$group\" : { \"_id\" : null , " +
"\"money_bank\" : { " +
"\"$sum\" : { " +
"\"$cond\" : [ { \"$eq\" : { \"$type\" : \"bank\"}} , " +
"\"$amount\" , 0]" +
"}" +
"}" +
"}" +
"}"));
However you can simplify it even more (although I admit the Java is still uglier than the JavaScript):
BasicDBList condList = new BasicDBList();
condList.add(new BasicDBObject("$eq", new BasicDBObject("$type", "bank")));
condList.add("$amount");
condList.add(0);
DBObject sumObj = new BasicDBObject("$sum", new BasicDBObject("$cond", condList));
DBObject group = new BasicDBObject("$group", new BasicDBObject("_id", null).append("money_bank", sumObj));
For some reason the BasicDBObjectBuilder is more verbose than using BasicDBObject.

MongoDB DBCollection.insert() returns null as WriteResult?

Will insert(List) return null?
WriteResult result = collection.insert(List<DBObject>);
result.getError() -->Throws NullPointeException
In the above snippet, what may cause the return of null for WriteResult?
Can you try providing a BasicDBList, which contains BasicDBObject instances.
For example:
BasicDBObject updateObject = new BasicDBObject();
BasicDBList dbList = createList(objects);
updateObject.append("$push", new BasicDBObject("collection", dbList));
WriteResult result = collection.insert(dbList);
...
private BasicDBList createList(List<SampleObject> list) {
BasicDBList result = new BasicDBList();
for (SampleObject obj: list) {
BasicDBObject dbObject = new BasicDBObject();
dbCar.append("name", obj.getName()); //for exmaple
result.add(dbObj);
}
return result;
}
It would probably return a NullPointerException because at the least the method is expecting a list that has at least one key to read in order to successfully insert something.
Else it would be inserting, technically, a non-existent document.

Add projection to morphia query

When doing queries with Morphia is it possible to limit the returned fields (specify a projection)?
Like this on the command line:
db.Institution.find({name: /^Berlin/}, {slug:1})
Or this with the Java driver:
BasicDBObject projection = new BasicDBObject("slug", 1);
collection.find(new BasicDBObject(),projection);
Thanks
You do, see https://code.google.com/p/morphia/wiki/Query#Ignoring_Fields
Pattern regex = Pattern.compile("^Berlin");
Query<InsitutionEntity> query = mongoDataStore.find(InsitutionEntity.class)
.field("name").equal(regex)
.retrievedFields(true, "slug").asList();
(Didn't test it, but it should work like this)
BasicDBObject filter = new BasicDBObject();
filter.append("name", "whoever");
BasicDBObject projection = new BasicDBObject();
projection.append("fieldOne", 1); // 1 == True, it shows the Field.
projection.append("fieldTwo", 1);
projection.append("_id", 0) // 0 == False, it does not show the "_id"
List list = MorphiaObject.datastore.getCollection(MyClass.class).find(filter, projection).toArray();
for (Object each : list) {
System.out.println("Each: " + each.toString());
}

Categories

Resources