MongoDB DBCollection.insert() returns null as WriteResult? - java

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.

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.

Mongodb Java - How to return all fields of a collection

With the driver Java Mongodb, I am looking for a way to return all fields of one collection.For example, I have a collection "people", how can I get all fields, I want output: 'id','name','city'...
Thanks a lot, I have finally got the answer.
DBCursor cur = db.getCollection("people").find();
DBObject dbo = cur.next();
Set<String> s = dbo.keySet();
From manual:
To return all documents in a collection, call the find method without a criteria document. For example, the following operation queries for all documents in the restaurants collection.
FindIterable<Document> iterable = db.getCollection("restaurants").find();
Iterate the results and apply a block to each resulting document.
iterable.forEach(new Block<Document>() {
#Override
public void apply(final Document document) {
System.out.println(document);
}
});
You'd need to decide on the number of samples that would make sense to you but this would pull the last 10 submissions.
Document nat = new Document().append("$natural",-1);
FindIterable<Document> theLastDocumentSubmitted = collection.find().limit(10).sort(nat);
ArrayList<String>fieldkeys = new ArrayList<String>();
for (Document doc : theLastDocumentSubmitted) {
Set<String> keys = doc.keySet();
Iterator iterator = keys.iterator();
while(iterator.hasNext()){
String key = (String) iterator.next();
String value = (String) doc.get(key).toString();
if(!fieldkeys.contains(key)) {
fieldkeys.add(key);
}
}
}
System.out.println("fieldkeys" + fieldkeys.toString());
Below code will return all fields from given collection.
MongoCollection<Document> mongoCollection = mongoDatabase.getCollection("collection_name");
AggregateIterable<Document> output = mongoCollection.aggregate(Arrays.asList(
new Document("$project", Document("arrayofkeyvalue", new Document("$objectToArray", "$$ROOT"))),
new Document("$unwind", "$arrayofkeyvalue"),
new Document("$group", new Document("_id", null).append("allkeys", new Document("$addToSet", "$arrayofkeyvalue.k")))
));
Below code will return all fields of people collection :
db.people.find()

How do I implement this MongoDB aggregation in Java

I have the following working MongoDB aggregation shell command:
db.followrequests.aggregate([{
$match: {
_id: ObjectId("551e78c6de5150da91c78ab9")
}
}, {
$unwind: "$requests"
}, {
$group: {
_id: "$_id",
count: {
$sum: 1
}
}
}]);
Which returns:
{ "_id" : ObjectId("551e78c6de5150da91c78ab9"), "count" : 7 }
I need to implement this in Java, I am trying the following:
List<DBObject> aggregationInput = new ArrayList<DBObject>();
BasicDBObject match = new BasicDBObject();
match.put("$match", new BasicDBObject().put("_id",new ObjectId(clientId)));
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", "$_id");
groupVal.put("count", new BasicDBObject().put("$sum", 1));
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
System.out.println(result);
}
I am getting an exception:
mongodb the match filter must be an expression in an object.
Can you please help me identify the error in the above code. Thanks!
Try to print the value of aggregationInput and you will realise that .put() does not return a BasicDBObject but just the previous value associated to the key you update. Therefore, when you do:
match.put("$match", new BasicDBObject().put("_id",new ObjectId(clientId)));
You are actually setting $match to null, as new BasicDBObject().put("_id",new ObjectId(clientId)) returns null.
Update you code to something like:
List <DBObject> aggregationInput = new ArrayList <DBObject> ();
BasicDBObject match = new BasicDBObject();
BasicDBObject matchQuery = new BasicDBObject();
matchQuery.put("_id", new ObjectId());
match.put("$match", matchQuery);
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", "$_id");
groupVal.put("count", new BasicDBObject().put("$sum", 1));
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
System.out.println(result);
}
Or, slightly more readable, use the fluent BasicDBObjectBuilder:
final DBObject match = BasicDBObjectBuilder.start()
.push("$match")
.add("_id", new ObjectId())
.get();
aggregationInput.add(match);
And it should work fine.
Each {} must be new DBObject. Use also .append(key,value) method to make more elegant.
Try this:
List<DBObject> pipeline = new ArrayList<DBObject>(Arrays.asList(
new BasicDBObject("$match", new BasicDBObject("_id",
new ObjectId("551e78c6de5150da91c78ab9"))),
new BasicDBObject("$unwind", "$requests"),
new BasicDBObject("$group",
new BasicDBObject("_id","$_id").append("count", new BasicDBObject("$sum", 1)))));
AggregationOutput output = followRequestsCol.aggregate(pipeline);
for (DBObject result : output.results()) {
System.out.println(result);
}
This is the final working version, based on the above suggestions
// Use mongodb aggregation framework to determine the count of followers
Integer returnCount = 0;
List aggregationInput = new ArrayList();
BasicDBObject match = new BasicDBObject();
BasicDBObject matchQuery = new BasicDBObject();
matchQuery.put("_id", new ObjectId(clientId));
match.put("$match", matchQuery);
aggregationInput.add(match);
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$requests");
aggregationInput.add(unwind);
BasicDBObject groupVal = new BasicDBObject();
groupVal.put("_id", null);
BasicDBObject sum = new BasicDBObject();
sum.put("$sum", 1);
groupVal.put("count", sum);
BasicDBObject group = new BasicDBObject();
group.put("$group", groupVal);
aggregationInput.add(group);
AggregationOutput output = followRequestsCol.aggregate(aggregationInput);
for (DBObject result : output.results()) {
returnCount = (Integer) result.get("count");
break;
}
return returnCount;

Resolving MongoDB error

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

MongoDB $in with $and Query

Is this type of query possible?
I need to query the database for data for a specified date for a set of specified stocks. So the data needs to have "this" date and be one of "these" symbols.
I have the following code:
public void findDateStockSet(String date, ArrayList<String> symbolSet) throws UnknownHostException {
this.stocks = this.getCollectionFromDB();
BasicDBObject objectToFind = new BasicDBObject();
List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
obj.add(new BasicDBObject("date", date));
obj.add(new BasicDBObject("symbol", new BasicDBObject("$in", symbolSet)));
objectToFind.put("$and", obj);
DBCursor cursor = this.stocks.find(objectToFind);
System.out.println("Finding Stocks");
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
System.out.println();
}
This always comes up null. Can someone explain how to make a query like this work?
You don't need to use $and operator, just build the query as the json below:
{ "date" : "20100223", "symbol" : { $in : [ "appl", "goog" ] } }
I like to use BasicDBObjectBuilder util class to build DBObjects. So your query will be:
DBObject query = BasicDBObjectBuilder.start()
.add("date", date)
.push("symbol")
.add("$in", symbolSet)
.get();

Categories

Resources