[MongoDB]How to retrieve values from an array in java mongo - java

i'm trying to retrieve and access to an array
{
"_id" : ObjectId("59325acd2d9d3069cf439512"),
"name" : "harry"
"fruits" : [ "apple", "orange" ]
}
so i manage to retrieve the whole document but i want to access to a specific value in my array (let's say 'apple')
BasicDBObject query = new BasicDBObject("name", new BasicDBObject("$regex", "harry"));
DBCursor results = coll.find(query);
while (results.hasNext()) { `
results.next().get("fruits");
}
i looked for some way to cast that object as an array but didn't succeed.
Thanks for your help.

Related

Retrieve all the documents matching the criteria in an array elements which is a subdocument

{
"_id" : ObjectId("577b54816081dd32cd3e2d60"),
"user" : ObjectId("577b54816081dd32cd3e2d5e"),
"journals" : [
{
"title" : "Journal Title2",
"desc" : "desx2",
"feeling" : 3,
"date" : ISODate("2016-07-05T06:32:45.404Z"),
"deleteFl" : true,
"_id" : ObjectId("577b548d6081dd32cd3e2d64")
},
{
"title" : "Journal Title3",
"desc" : "desx3",
"feeling" : 3,
"date" : ISODate("2016-07-05T06:49:00.156Z"),
"deleteFl" : false,
"_id" : ObjectId("577b585c6081dd32cd3e2d6d")
},
{
"title" : "Journal Title4",
"desc" : "desx4",
"feeling" : 3,
"date" : ISODate("2016-07-05T06:49:06.700Z"),
"deleteFl" : false,
"_id" : ObjectId("577b58626081dd32cd3e2d70")
}
]
}
Above is my document structure
now, I need all the journal documents whose deleteFl = false.
I tried in this way using Java Mongo driver
getDatabase().getCollection("journals").find(and(eq("user", user), eq("journals.deleteFl", false)));
but still it gives me back all the documents including "deleteFl": true. any help here ?
Actually, your query returns 1 document, because the data is inside 1 document. What you want is to limit the returning fields of a document (limit subdocuments).
Note: You can do that using elemMatch in the projection, to limit the fields returned by the query. But elemMatch will return just one subdocument. (I posted a deleted wrong answer using elemMatch)
When you want all subdocuments and only specific subdocuments from inside an array, you need to use the aggregation pipeline.
Here is a tested code that does what you want (just change DB and colelction name):
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("test");
MongoCollection collection = db.getCollection("test");
Iterable<Document> output = collection.aggregate(asList(
new BasicDBObject("$unwind", "$journals"),
new BasicDBObject("$match", new BasicDBObject("journals.deleteFl", false))
));
for (Document dbObject : output)
{
System.out.println(dbObject);
}

Remove [ "" : from mongoDb result using Java

To remove the "_id" from the mongo result I use :
DBObject allQuery = new BasicDBObject();
DBObject removeIdProjection = new BasicDBObject("_id", 0);
data.addAll(collection.find(allQuery , removeIdProjection).toArray());
The results of this query is :
{ "" : { [
{
"test1" : "test1"
{
}]}
How to remove { "" : so result is of format :
[
{
"test1" : "test1"
}
]
You are trying to put result in json object which add extra brackets here.
toArray() converts type cursor to list so you need to store it in list. You can iterate this list to access elements. You should use following code to get expected result:
DBObject allQuery = new BasicDBObject();
DBObject removeIdProjection = new BasicDBObject("_id", 0);
List cursor = collection.find(allQuery , emoveIdProjection).toArray();
System.out.println("result: " + cursor);

mongo and java finding nested keys and values

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()));

Updating Nested Embedded Documents in mongodb

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.

MongoDB/Java SDK: Query elements with a value in array

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.

Categories