How to combine $in and max in MongoDb? - java

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.

Related

Increment value in a subdocument in MongoDB [duplicate]

This question already has answers here:
How to update value of specific embedded document, inside an array, of a specific document in MongoDB?
(4 answers)
Closed 5 years ago.
I have a document in my collection
{
"_id" : ObjectId("59bd65b281a24497a0b3b401"),
"user_id" : "1",
"is_placed" : false,
"items" : [
{
"product_id" : 1,
"units" : 0
},
{
"product_id" : 2,
"units" : 0
}
]
}
I want to increment value of 'units' for product_id = 1. Here is what my code looks like:
MongoClient mongoConnection = new MongoClient("localhost", 27017);
try {
MongoDatabase db = mongoConnection.getDatabase("mydb");
MongoCollection<Document> collection = db.getCollection("orders");
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("user_id", "1");
whereQuery.put("is_placed", false);
whereQuery.put("product_id", 1);
BasicDBObject incValue = new BasicDBObject("items.units", 1);
BasicDBObject intModifier = new BasicDBObject("$inc", incValue);
collection.updateOne(whereQuery, intModifier);
} catch (Exception e) {
e.printStackTrace();
}
It does not throw any error. But neither does it increment the value. How do I achieve it? Also, is it possible to increment it only if product_id = 1 exists else put product_id = 1?
For updating an embedded document in an array, you should use $ operator. I cannot see you use it anywhere in your code. Your code may be, should be like this:
MongoClient mongoConnection = new MongoClient("localhost", 27017);
try {
MongoDatabase db = mongoConnection.getDatabase("db");
MongoCollection<Document> collection = db.getCollection("orders");
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("user_id", "1");
whereQuery.put("is_placed", false);
whereQuery.put("items.product_id", 1);
BasicDBObject incValue = new BasicDBObject("items.$.units", 1);
BasicDBObject intModifier = new BasicDBObject("$inc", incValue);
collection.updateOne(whereQuery, intModifier);
} catch (Exception e) {
e.printStackTrace();
}

find in MongoCollection<Document>

I have a MongoCollection<Document> in which I assign a collection.
I'm trying to find a user by his id.
user = (Document) usersCollection.find(new Document("_id", username));
with that I'm getting an error
java.lang.ClassCastException: com.mongodb.FindIterableImpl cannot be
cast to org.bson.Document
When I try
BasicDBObject query = new BasicDBObject();
BasicDBObject fields = new BasicDBObject("_id", username);
usersCollection.find(query, fields);
I'm getting an error
The method find(Bson, Class) in the type MongoCollection is not applicable for the arguments (BasicDBObject, BasicDBObject)
Try to create a filter to pass to the find() method to get a subset of the documents in your collection. For example, to find the document for which the value of the _id field is test, you would do the following:
import static com.mongodb.client.model.Filters.*;
MongoClient client = new MongoClient();
MongoDatabase database = client.getDatabase("mydb");
MongoCollection<Document> collection = database.getCollection("mycoll");
Document myDoc = collection.find(eq("_id", "test")).first();
System.out.println(myDoc.toJson());
Your issue is that you assume that the find() method returns a single Document. It doesn't. It returns a list of them.
In MongoDB 2 Java driver there was a method on the DBCollection class named findOne(). In the MongoDB 3 Java driver API, the findOne() method isn't there. So your new code for finding exactly one document becomes similar too this one:
collection.find(eq("_id", 3)).first()
where eq("_id", 3) is called a filter on your collection.
MongoCollection<Document> filterCriteriaDoc = mongoDatabase.getCollection("documentName");
Document filterDoc = new Document();
filterDoc.put("col1", "value");
filterDoc.append("col2", "value");
filterDoc.append("col2", "value");
Iterator<Document> iter = filterCriteriaDoc.find(filterDoc).iterator();
iter.next() can give you document .
If you using IP to connect to MongoDb here how you do it change HEREYOURIP
import static com.mongodb.client.model.Filters.eq;
public static Document GetDocumentFromDataBase(String dataBase,String DBcollection,String field, String value) {
MongoClient mongoClient = new MongoClient( " HEREYOURIP ",27017 );
MongoDatabase database = mongoClient.getDatabase(dataBase);
MongoCollection<Document> collection = database.getCollection(DBcollection);
Document myDoc = collection.find(eq(field, value)).first();
mongoClient.close();
return myDoc;}
edited found other way do it
public static String GetFromDB(String DATABASE_NAME,String collectionName, String field, String value) {
String valueBack;
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("_id", new ObjectId(value));
MongoClient mongoClient = new MongoClient(System.getenv("HERE_YOUR_DB_IP"), 27017);
MongoDatabase database = mongoClient.getDatabase(DATABASE_NAME);
MongoCollection<Document> collection = database.getCollection(collectionName);
Document myDoc = collection.find(whereQuery).first();
if (myDoc != null) {
valueBack = myDoc.toString();
mongoClient.close();
return valueBack;
}
mongoClient.close();
return null;
}
Do this -
MongoClient client = new MongoClient();
DBObject resultObject = new BasicDBObject("_id", username);
MongoDatabase database = client.getDatabase("DBNAME");
MongoCollection<Document> collection = database.getCollection("COLLECTION_NAME");
DBObject dbObject = new BasicDBObject("_id", username);
resultObject = collection.find(dbObject).next();
String result = resultObject.get(YOUR_COLOUM_NAME);

How to Query MongoDB Using Child Nodes in Java

I'm trying to query mongodb with java. The name of my collection is: reads. Here is an example of a specific document I'm querying for:
{
"_id" : {
"d" : "B66929932",
"r" : "15500304",
"eT" : ISODate("2014-09-29T12:03:00Z")
},
"v" : 169000,
"iT" : ISODate("2015-04-10T20:42:07.577Z")
}
I'm trying to query where r = 15500304, eT = 2014-09-29T12:03:00Z and v = 169000. I'm able to do this in mongo pretty easily:
db.reads.find({ "_id.r" : "15500304", "_id.eT" : ISODate("2014-09-29T12:03:00Z"), "$where" : "this.v == 169000;"}).pretty()
I'm unable to figure out how to structure this in java. So far I've got:
DBCollection collection = db.getCollection("reads");
BasicDBObject andQuery = new BasicDBObject();
List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
obj.add(new BasicDBObject("_id.r", "15500304"));
obj.add(new BasicDBObject("_id.eT", "2014-09-29T12:03:00Z"));
obj.add(new BasicDBObject("v", 169000));
andQuery.put("$and", obj);
DBCursor cursor = collection.find(andQuery);
while(cursor.hasNext()){
System.out.println(cursor.next());
}
My Question is: How do I query using these child nodes and return the matching document?
I'm unable to find any clear advice/examples online. Any and all advice is very appreciated.
You were close. Modify your query to:
DBCollection collection = db.getCollection("reads");
BasicDBObject query = new BasicDBObject();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
String dateInString = "2014-09-29T12:03:00Z";
Date date = df.parse(dateInString);
query.append("status.name", "Expired")
.append("_id.eT", date)
.append("v", 169000);
Or using QueryBuilder:
DBObject query = QueryBuilder.start()
.put("_id.r").is("15500304")
.put("_id.eT").is(date)
.put("v").is(169000)
.get();
DBCursor cursor = collection.find(query);
while(cursor.hasNext()){
System.out.println(cursor.next());
}

Use MongoDB db.collection.remove(query) in java

Is there a way in the MongoDB Java driver to call the db.collection.remove(query) method that I see in the MongoDB shell documentation?
That is, I know the exact criteria that I need to find all the documents I want to delete from MongoDB, but I can't find a way to make one call to remove those records in one trip. All that I can figure out is to find the documents and then delete them one by one.
I see this
http://docs.mongodb.org/manual/reference/method/db.collection.remove/
which implies there should be a way to do it, but I can't figure out the Java calls to get me that to that call.
Thank you for your help
To remove documents with an age property of 25.
MongoClient mongo = new MongoClient(new ServerAddress("localhost", 27017));
DB db = mongo.getDB("thedb");
DBCollection collection = db.getCollection("test");
BasicDBObject query = new BasicDBObject();
query.append("age", 25);
collection.remove(query);
DBCollection and BasicDBObject are two of the most important classes in the Java API.
Also to remove specific values from you document you can use following code with Mongo Java 3.2
Document docToDelete = new Document("Designation", "SE-1");
objDbCollection.findOneAndUpdate(new Document("Company", "StackOverflow"), new Document("$unset", docToDelete));
Above code will first find document having company = StackOverflow and then unset (remove) Designation = SE-1 key/value from that document.
Add and Update Mongo
public class App {
public static void main(String[] args) {
try {
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB("yourdb");
// get a single collection
DBCollection collection = db.getCollection("dummyColl");
//insert number 1 to 10 for testing
for (int i=1; i <= 10; i++) {
collection.insert(new BasicDBObject().append("number", i));
}
//remove number = 1
DBObject doc = collection.findOne(); //get first document
collection.remove(doc);
//remove number = 2
BasicDBObject document = new BasicDBObject();
document.put("number", 2);
collection.remove(document);
//remove number = 3
collection.remove(new BasicDBObject().append("number", 3));
//remove number > 9 , means delete number = 10
BasicDBObject query = new BasicDBObject();
query.put("number", new BasicDBObject("$gt", 9));
collection.remove(query);
//remove number = 4 and 5
BasicDBObject query2 = new BasicDBObject();
List<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(5);
query2.put("number", new BasicDBObject("$in", list));
collection.remove(query2);
//print out the document
DBCursor cursor = collection.find();
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
collection.drop();
System.out.println("Done");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (MongoException e) {
e.printStackTrace();
}

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.

Categories

Resources