Query fields in a MongoDB Collection. - java

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.

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
}

Get MongoDB document by ID on 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));

Auto increment sequence in mongodb using java

Hi I want to auto increment _id in mongodb using java. I am completely new to this. In the document I found the solution like this:
db.counters.insert(
{
_id: "userid",
seq: 0
}
)
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Sarah C."
}
)
Can any one suggest how do I do this using java ? I am completely new to this.
Using Create an Auto-Incrementing Sequence Field first you should create collection using mongoDB shell and collection should be as :
db.counters.insert(
{
_id: "userid",
seq: 0
})
So you get counters collections which contains field like _id,seq, now create getNextSequence function in java and this function having parameter userid as string so getNextSequence function like this :
public static Object getNextSequence(String name) throws Exception{
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// Now connect to your databases
DB db = mongoClient.getDB("demo");
DBCollection collection = db.getCollection("counters");
BasicDBObject find = new BasicDBObject();
find.put("_id", name);
BasicDBObject update = new BasicDBObject();
update.put("$inc", new BasicDBObject("seq", 1));
DBObject obj = collection.findAndModify(find, update);
return obj.get("seq");
}
The above function return seq count and used this function in main method as like :
public static void main(String[] args) throws Exception {
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// Now connect to your databases
DB db = mongoClient.getDB("demo");
DBCollection collection = db.getCollection("counters");
BasicDBObject document = new BasicDBObject();
document.put("_id", getNextSequence("userid"));
document.put("name","Sarah C.");
collection.insert(document); // insert first doc
document.put("_id", getNextSequence("userid"));
document.put("name", "Bob D.");
collection.insert(document); // insert second doc
}
Now in counters collection contains three documents which contains name as Sarah C. and Bob D. respectively and one default documents which we inserted manually at first time and it increment seq like this { "_id" : "userid", "seq" : 2 }
DBCollection collection = database.getCollection("Table Name");
DBObject modifier = new BasicDBObject("counter", 1);
DBObject incQuery = new BasicDBObject("$id", modifier);

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

Categories