I am very new to MongoDB and its Java... SDK? Api? I have a very simple question, but I haven't been able to find a satisfactory answer.
Let's say I have a collection of instances that are like:
{
"_id": {
"$oid": "5156171e5d451c136236e738"
},
"_types": [
"Sample"
],
"last_z": {
"$date": "2012-12-30T09:12:12.250Z"
},
"last": {
"$date": "2012-12-30T04:12:12.250Z"
},
"section": "5156171e5d451c136236e70f",
"s_mac": "AA:AA:AA:AA:AA:AA",
"_cls": "Sample",
}
And I have a hard-coded Java list:
static List<String> MAC_LIST = Arrays.asList("90:27:E4:0E:3D:D2", "A8:26:D9:E6:1D:8B");
What I would like to know is how to query the MongoDB so it will give me all the objects whose s_mac field has a value that appears in the MAC_LIST List.
I'm guessing I should use the $in operator, but I don't know how to translate it to Java code.
Any hint or link to pages with explanations of the use of the $in operator through the Java SDK would be appreciated!
Here is a contrived example that works for me (driver version 2.10.1) - you can adjust the IP address and run it as is to check if you get the same outcome:
public void gss() throws Exception{
MongoClient mongo = new MongoClient("192.168.1.1");
DB db = mongo.getDB("test");
DBCollection collection = db.getCollection("stackoverflow");
DBObject o1 = new BasicDBObject();
o1.put("s_mac", "AA:AA:AA:AA:AA:AA");
o1.put("_cls", "Sample1");
DBObject o2 = new BasicDBObject();
o2.put("s_mac", "90:27:E4:0E:3D:D2");
o2.put("_cls", "Sample2");
DBObject o3 = new BasicDBObject();
o3.put("s_mac", "A8:26:D9:E6:1D:8B");
o3.put("_cls", "Sample3");
collection.insert(o1, o2, o3);
System.out.println(collection.find().count());
List<String> MAC_LIST = Arrays.asList("90:27:E4:0E:3D:D2", "A8:26:D9:E6:1D:8B");
System.out.println(collection.find(new BasicDBObject("s_mac", new BasicDBObject("$in", MAC_LIST))).count());
}
It inserts the following documents:
{ "_id" : ObjectId("5159ff98567e143bff0668e9"),
"s_mac" : "AA:AA:AA:AA:AA:AA",
"_cls" : "Sample1"
}
{ "_id" : ObjectId("5159ff98567e143bff0668ea"),
"s_mac" : "90:27:E4:0E:3D:D2",
"_cls" : "Sample2"
}
{ "_id" : ObjectId("5159ff98567e143bff0668eb"),
"s_mac" : "A8:26:D9:E6:1D:8B",
"_cls" : "Sample3"
}
A call to collection.find().count() returns 3 and a call to collection.find(new BasicDBObject("s_mac", new BasicDBObject("$in", MAC_LIST))).count() returns 2 which I think is what you expected.
Related
I have a documents in mongo db as follows. I want to get and update the document having policyMap equals CostCalculation.In this CostCalculation has array format update in array elements such as 'policyName' have 'CostCalculationPolicyuserDefine' and set 'policyDes' = 'New Value' Please suggest the java code to solve this.
I searched mongo operartors but couldn't get it.
Sample mongo db document structure.
{
"policyMap" : {
"CostCalculation" : [{
"policyName" : "CostCalculationPolicyuserDefine",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
},
{
"policyName" : "CostCalculationPolicyuserDefine1",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
}]
},
"bsVer" : 2,
"bsFlag" : true,
"crBy" : "xxxxx",
"crDate" : NumberLong("1440138385345"),
"entNm" : "xxxx"
}
{
"policyMap" : {
"CostValue" : [{
"policyName" : "CostValuePolicyuserDefine",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
},
{
"policyName" : "CostCalculationPolicyuserDefine1",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
}]
},
"bsVer" : 2,
"bsFlag" : true,
"crBy" : "xxxxx",
"crDate" : NumberLong("1440138385345"),
"entNm" : "xxxx"
}
My sample java code
DBCollection coll = db.getCollection("nestedtest");
BasicDBObject searchDocument = new BasicDBObject();
searchDocument.put( "policyMap ", new BasicDBObject("$exists", new BasicDBObject("$eq", "CostCalculation")));
coll.remove(searchDocument);
What would be the similar java code to get the correct result.
Thanks.
This code works using Mongo 3 java drivers. It removes the need for all the BasicDBObjects that are in your code:
MongoClientURI uri = new MongoClientURI("mongodb://localhost:27017");
MongoClient client = new MongoClient(uri);
initialiseCollection(client);
Bson filter = Filters.exists("policyMap.costCalculation");
client.getDatabase("test").getCollection("test").deleteOne(filter);
DBCollection coll = db.getCollection("minnalPolicyMetadata");
BasicDBObject searchDocument = new BasicDBObject();
searchDocument.put("policyMap.CostCalculation",new BasicDBObject("$exists",true));
DBCursor cursor = coll.find(searchDocument);
if(cursor.count() != 0){
while(cursor.hasNext())
System.out.println(cursor.next());
}
In this way i solved this problem.Use exists operator in mongo
I want to insert the following JSON into the Mongodb collection using java API . Here bookmarks is an arrayList of bookmarks POJO .
{
"_id": 5,
"email": "xxx#gmail.com",
"bookmarks": [
{
"name": "chipotle",
"category": "restaurant",
"stats": "203 likes",
"tried": true
},
{
"name": "olivegarden",
"category": "restaurant",
"stats": "203 likes",
"tried": true
}
]
}
I used the following API . but it doesn't seem to work
BasicDBObject document = new BasicDBObject();
document.append("email", userList.get(i).getEmail());
document.append("bookmarks", userList.get(i).getBookmarksList() ) ;
WriteResult result = collection.insert(document);
This is the error I got when I ran the unit test .
java.lang.IllegalArgumentException: can't serialize class com.xxx.pojo.Bookmark
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:272)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:173)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:119)
at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:27)
at com.mongodb.OutMessage.putObject(OutMessage.java:289)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:239)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)
at com.mongodb.DBCollection.insert(DBCollection.java:76)
at com.mongodb.DBCollection.insert(DBCollection.java:60)
at com.mongodb.DBCollection.insert(DBCollection.java:105)
Even after making the Bookmark POJO serializable I got the same error again .So I guess am using the Java API for insert in a wrong way . How to map the POJO directly into the mongodb element ?
As the error suggests can't serialize class com.xxx.pojo.Bookmark , which means that the List containing Bookmark.class can't be directly inserted in BasicDBObject document.
You need to use : BasicDBList as follows:
BasicDBList bookmark_list = new BasicDBList();
List<Bookmark> bmk_list = userList.get(i).getBookmarksList();
for(int i=0;i<bmk_list.size();i++)
{
String name = bmk_list.get(i).getName();
String category = bmk_list.get(i).getCategory();
String stats = bmk_list.get(i).getStats();
boolean tried = bmk_list.get(i).getTried();
DBObject db_obj = new BasicDBObject();
db_obj.put("name",name);
db_obj.put("category",category);
db_obj.put("stats",stats);
db_obj.put("tried",tried);
bookmark_list.add(db_obj);
}
Now add this bookmark_list in your document as follows:
BasicDBObject document = new BasicDBObject();
document.append("email", userList.get(i).getEmail());
document.append("bookmarks", bookmark_list ) ;
WriteResult result = collection.insert(document);
my mongo collections contains following documents
{
"_id" : ObjectId("52d43cd29b85346a4aa6fe17"),
"windowsServer" : [
{
"topProcess" : [ ]
}]
},
{
"_id" : ObjectId("52d43cd29b85346a4aa6fe18"),
"windowsServer" : [
{
"topProcess" : [ {pid:1,name:"wininit"}]
}]
}
Now in my java code I want to used only topProcess in above case I want only second document which topProcess having some data. For this I write my java code as below
BasicDBObject criteria = new BasicDBObject();
BasicDBObject projections = new BasicDBObject();
criteria.put("windowsServer.topProcess", new BasicDBObject("$ne", "[]"));
projections.put("windowsServer.topProcess",1);
DBCursor cur = coll.find(criteria,projections);
while(cur.hasNext() && !isStopped()) {
String json = cur.next().toString();
}
when I execute above code and print json string it also contains the both topProcess. Can any one knows how should I get only second documents topProcess?
Try this one (and translate it to your java driver):
"windowsServer.topProcess": {$not: {$size: 0} }
In your code, you only have mistake in the following line.
criteria.put("windowsServer.topProcess", new BasicDBObject("$ne", "[]"));
You try to compare if an array is empty by using brackets as a String. You can use BasicDBList() for an empty array. Update above line with the following and it should work.
criteria.put("windowsServer.topProcess", new BasicDBObject("$ne", new BasicDBList()));
I am new to mongodb. Plz help me with this.
I need a document like this
employee{
_id:111,
name:xxx,
dependents : [ {
name:a,
age:51,
dep_children:[{name:aa}{name:bb}{name:c}]
}
{
name:b,
age:52,
dep_children:[{name:aa}{name:bb}{name:c}]
}
{
name:c,
age:51,
dep_children:[{name:aa}{name:bb}{name:cc}]
}
]
}
I am using the below script to migrate data for SQL and update it into mongoDB
My code looks something like this:
while(personcount>=0)
{
BasicDBObject doc = new BasicDBObject("_id",ind1.get(count)).
append("name",ind2.get(count));
coll.insert(doc);
while(dependentcount>0)
{
BasicDBObject querymongo = new BasicDBObject();
querymongo.put( "name",ind.get(count));
BasicDBObject tenant = new BasicDBObject();
tenant.put("name",indsa.get(innercount) );
tenant.put("age", indsa2.get(innercount));
BasicDBObject update = new BasicDBObject();
update.put("$push", new BasicDBObject("dependents",tenant));
coll.update(querymongo, update,true,true);
while(kidcount>0)
{
BasicDBObject querymongofact = new BasicDBObject();
querymongokid.put( "dependent.name",indsa.get(innercount));
BasicDBObject tenantkid = new BasicDBObject();
tenantkid .put("name",indfact.get(innercountfact) );
BasicDBObject updatekid = new BasicDBObject();
updatekid .put("$push", new BasicDBObject("dependent.dep_children",tenantkid));
coll.update(querymongokid, updatekid ,true,true);
}
}
}
when we print querymongokid and updatekid, the data inside it are expected values itself. This code is not throwing any error. But in data base the only dep_children data is not getting updated . I am not getting wt went wrong. please help me
Thanks in advance
Your last query fails in the mongo driver in a sense that the update has no effect - but it's not an actual error. Just let me reproduce what you are doing in the mongo shell:
> db.coll.insert({_id:1,name:"name1"})
> db.coll.update({name:"name1"}, {"$push": {dependents: {name:"a", age:50}}})
> db.coll.update({name:"name1"}, {"$push": {dependents: {name:"b", age:55}}})
> db.coll.findOne()
{
"_id" : 1,
"dependents" : [
{
"name" : "a",
"age" : 50
},
{
"name" : "b",
"age" : 55
}
],
"name" : "name1"
}
> db.coll.update({"dependents.name": "a"}, {"$push": {"dependents.dep_children": {name:"aa"}}})
can't append to array using string field name: dep_children
> db.coll.update({"dependents.name": "a"}, {"$push": {"dependents.$.dep_children": {name:"aa"}}})
> db.coll.findOne()
{
"_id" : 1,
"dependents" : [
{
"age" : 50,
"dep_children" : [
{
"name" : "aa"
}
],
"name" : "a"
},
{
"name" : "b",
"age" : 55
}
],
"name" : "name1"
}
Unfortunately, I have very little experience with the native mongo java driver (I'm usually on Spring data), but changing your line
updatekid.put("$push", new BasicDBObject("dependent.dep_children",tenantkid));
to
updatekid.put("$push", new BasicDBObject("dependent.$.dep_children",tenantkid));
should do the trick as well.
The reason for that behavior is that "dependent.dep_children" is not a valid selector as it corresponds to "go to field dep_children within the subdocument dependent". However, "dependent" happens to be an array without any fields. The $ replaces an explicit index and will make sure the correct subdocument from your query is selected.
Also see here for a less error-prone formulation of your query - without using $elemMatch it will only work if your query uniquely identifies a certain array element. With $elemMatch it will always work, but only update the first match.
I pull the following document from MongoDB into Java:
{
"_id": {
"$oid": "5076371389d22e8906000000"
},
"item": {
"values": [
{
"value1": [
4958,
3787,
344
],
"value2": [
4,
13,
23
]
}
],
"name": "item1"
}
}
Using
M mongo = new M("database", "collection");
String query = "{\"item.name\":\"item1\"}";
DBCursor cur = mongo.collection.find(mongo.query(query));
while(cur.hasNext()) {
System.out.println(cur.next().toString());
// I need to access value1 array.
}
I need to access value1 array, I also need to pull the whole document, so I cannot just ask Mongo to return this for me. Its like I am pulling this document, need to do a calculation and use the document again.
I understand this result can be converted to a map. But how would I be able to navigate through it since it is a multidimentional object. Thanks
Try this:
//try catch omitted
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB("db");
BasicDBObject query = new BasicDBObject("item.name","item1");
DBCursor cur = db.getCollection("items").find(query);
while(cur.hasNext()) {
BasicDBObject object = (BasicDBObject) cur.next();
BasicDBObject item = (BasicDBObject) object.get("item");
BasicDBList valueslist = (BasicDBList) item.get("values");
BasicDBObject values = (BasicDBObject) valueslist.get(0);
BasicDBList value1 = (BasicDBList) values.get("value1");
System.out.println(value1);
}
You can optimise it, but I hope you get the point and it helps.
cheers