Get MongoDB document by ID on Java - java

I have a set of ID's of documents which I add previously in MongoDB.
Then I try to get Document from ID.
String idString = "57f8f50977c8a5b8757f261a";
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("_id", idString);
DBCursor cursor = table.find(whereQuery);
if(cursor.hasNext())
{
System.out.println("FOUND!" + cursor.next());
}
I get zero results.
But, if I call another field
It works and return me document.
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("datachain", "AA");
DBCursor cursor = table.find(whereQuery);
if(cursor.hasNext())
{
System.out.println("FOUND!" + cursor.next());
}
FOUND!{ "_id" : { "$oid" : "57f8f50977c8a5b8757f261b"} , "datachain" : "AA" , "createdDate" : { "$date" : "2016-10-08T13:30:49.588Z"}}
What I do wrong? Why I can't find document by ID's?
Thnx!
UPD:
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("_id", new ObjectId("57f8f50977c8a5b8757f261a"));
DBCursor cursor = table.find(whereQuery);
Same, no result founded.

You have to pass the idString as an ObjectId.
whereQuery.put("_id", new ObjectId(idString));

Related

How to fetch the particular data from Mongo subdocument in java?

I have tried to fetch data for the particular column value in the mongo document but its displaying whole data.
Following is the mongo document:
{
"_id" : ObjectId("59db2321811a592384865711"),
"User_ID" : "demo",
"Project_ID" : "demo-1",
"Project_Information" : {
"Project_Description" : "Sample",
"Primary_Building_Type" : "Office",
"State" : "AR",
"Analysis_Type" : "1",
"Project_Billing_Number" : "WY",
"Country" : "USA",
"Climate_Zone" : "3A",
"Zip_Code" : "71611"
"City" : "WA",
"Units" : "IP"
}
}
I want to fetch the following output:
[
{
"User_ID": "demo",
"Project_Description": "Sample"
}]
I have tried using dot: Project_Information.Project_Description.The code is as below:
public Object[] addDemo1(String User_ID) throws Exception {
DB db = ConnectToDB.getConnection();
Properties prop = new Properties();
InputStream input = null;
input = GetProjectStatus.class.getClassLoader().getResourceAsStream("config.properties");
prop.load(input);
String col = prop.getProperty("COLLECTION_PI");
System.out.println("data is.." + col);
DBCollection collection = db.getCollection(col);
BasicDBObject obj = new BasicDBObject();
BasicDBObject fields = new BasicDBObject();
BasicDBObject fields2 = new BasicDBObject();
List<DBObject> obj1 = null;
if (User_ID != null && !User_ID.equals("") && User_ID.length() > 0) {
obj.put("User_ID", User_ID);
fields.put("_id", 0);
fields.put("User_ID", 1);
fields.put("Project_ID", 1);
fields.append("Project_Information.Project_Description", "Project_Description");
BasicDBObject fields1 = new BasicDBObject();
fields1.put("User_ID", User_ID);
}
DBCursor cursor = collection.find(obj, fields);
System.out.println("count is:" + cursor.count());
obj1 = cursor.toArray();
System.out.println("" + obj1);
cursor.close();
db.getMongo().close();
return obj1.toArray();
}
But it displays the whole structure of Project_Information.
Please specify how to achieve this. Thanks for help.
Using a 2.x MongoDB Java Driver
Here's an example using the MongoDB 2.x Java driver:
DBCollection collection = mongoClient.getDB("stackoverflow").getCollection("demo");
BasicDBObject filter = new BasicDBObject();
BasicDBObject projection = new BasicDBObject();
// project on "Project_Information.Project_Description"
projection.put("Project_Information.Project_Description", 1);
DBCursor documents = collection.find(filter, projection);
for (DBObject document : documents) {
// the response contains a sub document under the key: "Project_Information"
DBObject projectInformation = (DBObject) document.get("Project_Information");
// the "Project_Description" is in this sub document
String projectDescription = (String) projectInformation.get("Project_Description");
// prints "Sample"
System.out.println(projectDescription);
// to return this single String value in an Object[] (as implied by your OP) just do create the Object[] like this and then return it ...
Object[] r = new Object[] {projectDescription};
// prints the entire projected document e.g.
// { "_id" : { "$oid" : "59db2321811a592384865711" }, "Project_Information" : { "Project_Description" : "Sample" } }
System.out.println(document.toString());
}
Using a 3.x MongoDB Java Driver
Here's an example using the MongoDB 3.x Java driver:
// this finds all documents in a given collection (note: no parameter supplied to the find() call)
// and for each document it projects on Project_Information.Project_Description
FindIterable<Document> documents =
mongoClient.getDatabase("...").getCollection("...")
.find()
// for each attrbute you want to project you must include its dot notation path and the value 1 ...
// this is the equivalent of specifying {'Project_Information.Project_Description': 1} in the MongoDB shell
.projection(new Document("Project_Information.Project_Description", 1));
for (Document document : documents) {
// the response contains a sub document under the key: "Project_Information"
Document projectInformation = (Document) document.get("Project_Information");
// the "Project_Description" is in this sub document
String projectDescription = projectInformation.getString("Project_Description");
// prints "Sample"
System.out.println(projectDescription);
// to return this single String value in an Object[] (as implied by your OP) just do create the Object[] like this and then return it ...
Object[] r = new Object[] {projectDescription};
// prints the entire projected document e.g. { "_id" : { "$oid" : "59db2321811a592384865711" }, "Project_Information" : { "Project_Description" : "Sample" } }
System.out.println(document.toJson());
}
Java libraries won't let you directly access using dot.
They have build in getter and setter methods.
You have not mentioned which package you are using.
Here's the query that you need:
db.mycol.find({},{User_ID:1,"Project_Information.Project_Description":1})
It will give:
{ "_id" : ObjectId("59db2321811a592384865711"),
"User_ID" : "demo",
"Project_Information" : { "Project_Description" : "Sample" }
}
You will have to convert the query in whatever format your package accepts.
Here's a tutorial:
https://www.mongodb.com/blog/post/getting-started-with-mongodb-and-java-part-i

Retrieve mongodb array element using java

I have this in my db.
{
"_id" : ObjectId("59424f41baaacf1f40815ae8"),
"first_name" : "Yazid",
"last_name" : "Amir",
"gender" : "Male",
"hobby" : ["Memanah", "Business", "Fusal", "Makan"]
}
Let say that I want to retrieve the "Business" from array hobby. So my code will be like this
MongoCollection collection = db.getCollection("customers");
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("first_name", "Yazid");
MongoCursor<Document> cursor = collection.find(whereQuery).iterator();
try {
while (cursor.hasNext()) {
Document str = cursor.next();
out.println(str.get("hobby.0")); // display specific field
}
} finally {
cursor.close();
}
However, the result is null.
Use a List<Document> to store your array
while (cursor.hasNext()) {
Document str = cursor.next();
List<Document> list = (List<Document>)str.get("hobby");
out.println(list.get(0)); // display specific field
}

How to write group by with add operation in MongoDB Java driver

In the following query , I'm doing addition to a field (This field having ISO date as value) then extracting hour from that field, then group by on hour
db.campaigns.aggregate([
{$group : { _id: {$hour:{$add:['$time', 19800000]}}}}
])
Sample record of the collection
db.campaigns.findOne()
{
"_id" : ObjectId("53c7afdab92be74745af9068"),
"time" : ISODate("2013-03-08T12:25:24.973Z"),
"type" : "annoying",
"PINGS" : 143
}
The above one is working fine in Mongo shell,
I'm trying write this query in Java
Here is my partial Java code
DBObject group2Fields = new BasicDBObject();
group2Fields.put("hour", new BasicDBObject("$hour", new BasicDBObject("$add",new BasicDBObject("time",19800000))));
DBObject group2 = new BasicDBObject("_id", group2Fields);
DBObject secondGroup = new BasicDBObject("$group", group2);
I'm getting "errmsg" : "exception: field inclusion is not allowed inside of $expressions"
try this:
DBObject group2Fields = new BasicDBObject();
BasicDBList addObjects = new BasicDBList();
addObjects.add("$time");
addObjects.add(19800000);
group2Fields.put("$hour", new BasicDBObject("$add", addObjects));
DBObject group2 = new BasicDBObject("_id", group2Fields);
DBObject secondGroup = new BasicDBObject("$group", group2);
Nesting calls in your code generally helps you to "visualise" the structure that you want:
BasicDBList addArgs = new BasicDBList();
addArgs.add("$time");
addArgs.add(19800000);
DBObject group = new BasicDBObject("$group",
new BasicDBObject("_id",
new BasicDBObject("$hour",
new BasicDBObject("$add", addArgs)
)
)
);
Which of course produces a group variable that serializes like so:
{ "$group" : { "_id" : { "$hour" : { "$add" : [ "$time" , 19800000]}}}}

Getting data from mongo db like we get in mysql?

I am inserting some value into mongodb in this way.
MongoClient mongo = new MongoClient( "localhost" , 27017 );
DB db = mongo.getDB("test");
DBCollection table = db.getCollection("paramDescMapper");
String key = UUID.randomUUID().toString();
String value = "{\"param0\":\"Car Make\",\"param1\":\"Car Model\",\"param2\":\"Car Variant\",\"param3\":\"Car Year\",\"param4\":\"Car Number\"}";
JSONObject jsonObject = new JSONObject(value);
// create a document to store key and value
BasicDBObject document = new BasicDBObject();
document.put("apiKey", key);
document.put("apiParamDesc", jsonObject.toString());
table.insert(document);
It is inserting data in this way.
{ "_id" : { "$oid" : "534251125f1ab7ec747298cd"} , "apiKey" : "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6" , "apiParamDesc" : "{\"param0\":\"Car Make\",\"param1\":\"Car Model\",\"param2\":\"Car Variant\",\"param3\":\"Car Year\",\"param4\":\"Car Number\"}"}
Now i want to get apiParamDesc value using apiKey. Like how we get data in mysql.
Select apiParamDesc where apiKey =
'1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6';
I googled a lot but could not found anything. This is how i am trying to get this apiParamDesc
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6");
DBCursor cursor = table.find(whereQuery);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
But this is giving me entire row. I want only apiParamDesc in a String.
Please help me.
Thanks
You can easily do it with aggregation framework. Below is the example which can resolve your issue:
// create our pipeline operations, first with the $match
DBObject match = new BasicDBObject("$match", new BasicDBObject("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6"));
// build the $projection operation
DBObject fields = new BasicDBObject("apiParamDesc", 1);
fields.put("_id", 0);
DBObject project = new BasicDBObject("$project", fields );
// run aggregation
AggregationOutput output = collection.aggregate( match, project);
You can also make use of only db.coll.find(< criteria >, < projection >);
BasicDBObject query = new BasicDBObject(new BasicDBObject("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6"), new BasicDBObject("apiParamDesc", 1).append("_id", 0));
//Which is equivalent to a follwoing query
//'db.coll.find({"apiKey": "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6"}, {"apiParamDesc": 1,"_id": 0});'
cursor = coll.find(query);
One more thing to update you on "I want only apiParamDesc in a String.", is if you are storing string like
"apiParamDesc" : "{\"param0\":\"Car Make\",\"param1\":\"Car Model\",\"param2\":\"Car Variant\",\"param3\":\"Car Year\",\"param4\":\"Car Number\"}
You cannot query on those sub level fields like param0, param1 ...
You data should look like :
{
"_id":{
"$oid":"534251125f1ab7ec747298cd"
},
"apiKey":"1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6",
"apiParamDesc":{
"param0":"Car Make",
"param1":"Car Model",
"param2":"Car Variant",
"param3":"Car Year",
"param4":"Car Number"
}
}
I want only apiParamDesc in a String.
You cannot however, you can get a document (object) returned with only the apiParamDesc as its single field (my Java is rusty):
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("apiKey", "1eb9b9e3-3af1-4b25-b7ea-1f2fcb1d9af6");
BasicDBObject fields = new BasicDBObject();
fields.put("apiParamDesc", 1);
fields.put("_id", 0);
DBCursor cursor = table.find(whereQuery, fields);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}

Query fields in a MongoDB Collection.

I am trying to query specific fields in a mongodb collection. Here is my code and output:
Mongo m = new Mongo();
DB db = m.getDB( "mydb" );
DBCollection coll = db.getCollection("student") ;
// adding data
BasicDBObject moz = new BasicDBObject();
moz.put("Name", "Mozammil");
coll.insert(moz);
DBCursor cursor = coll.find();
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
This returns the following:
{ "_id" : { "$oid" : "4f5a4477c5e80f71ece56797"} , "Name" : "Mozammil"}
However, i want only the Name part. Googling around, this should do the job.
DBCursor cursor = coll.find({}, {'Name':1});
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
But it is not working. Help please?
You can use get on the returned document by the cursor to get the field you are looking for. Like this:
System.out.println(cursor.next().get("key"));
I know you already accepted an answer, but it isn't exactly what you were asking for.
Here is some working code:
// get Mongo set up...
Mongo m = new Mongo();
DB db = m.getDB( "test" );
DBCollection coll = db.getCollection("test");
// insert a test record
coll.insert(new BasicDBObject("Name","Wes").append("x", "to have a second field"));
// create an empty query
BasicDBObject query = new BasicDBObject();
// configure fields to be returned (true/1 or false/0 will work)
// YOU MUST EXPLICITLY CONFIGURE _id TO NOT SHOW
BasicDBObject fields = new BasicDBObject("Name",true).append("_id",false);
// do a query without specifying fields (and print results)
DBCursor curs = coll.find(query);
while(curs.hasNext()) {
DBObject o = curs.next();
System.out.println(o.toString());
}
// do a query specifying the fields (and print results)
curs = coll.find(query, fields);
while(curs.hasNext()) {
DBObject o = curs.next();
System.out.println(o.toString());
}
The first query outputs:
{ "_id" : { "$oid" : "4f5a6c1603647d34f921f967"} , "Name" : "Wes" , "x" : "to have a second field"}
And the second query outputs:
{ "Name" : "Wes"}
Take a look at DBCollection.find
BasicDBObject query = new BasicDBObject(); // because you have no conditions
BasicDBObject fields = new BasicDBObject("Name",1);
coll.find(query, fields);
collection.find().projection(Projections.include("Name"))
this worked such well!!!
BasicDBObject query = new BasicDBObject();
BasicDBObject fields = new BasicDBObject();
fields.put("name", 1);
DBCursor cursor = collection.find(query, fields);
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
To get all nested keys:
public static ArrayList<String> getKeys(Document it1) throws JSONException {
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> resultTemp;
String temp;
Document doc;
JSONArray jsa;
int len, i;
System.out.println(it1);
String js = it1.toJson();
JSONObject js1 = new JSONObject(js);
Iterator<String> keys = js1.keys();
while (keys.hasNext()) {
String key = keys.next();
if (key.equals("_id")) {
result.add(key);
continue;
}
System.out.println(key);
temp = js1.get(key).toString();
if (temp.contains(":")) {
jsa = new JSONArray(temp);
len = jsa.length();
for (i = 0; i < len; i++) {
JSONObject object = jsa.getJSONObject(i);
doc = Document.parse(object.toString());
System.out.println(doc);
resultTemp = getKeys(doc);
for (String keyTemp : resultTemp) {
if (!result.contains(key + "." + keyTemp))
result.add(key + "." + keyTemp);
}
}
} else {
result.add(key);
}
}
return result;
}
db.getCollection('users').aggregate([
{"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}},
{"$unwind":"$arrayofkeyvalue"},
{"$group":{"_id":null,"columns":{"$addToSet":"$arrayofkeyvalue.k"}}}
])
Use the above query it will give you all the fields of a document. In this you will get nested field also.

Categories