I'm using mongodb 3.2 version.I'm trying to use the following query for the below dataset.But I'm unable to fetch the records due to the following exception:
Exception in thread "main" java.util.NoSuchElementException
at com.mongodb.QueryResultIterator.next(QueryResultIterator.java:103)
My dataset:
BasicDBObject obj3 = new BasicDBObject();
obj3.put("name", "Dhoni");
obj3.put("location", "Ranchi");
obj3.put("Profession", "Cricketer");
obj3.put("number", 3);
BasicDBObject obj4 = new BasicDBObject();
obj4.put("name", "Sakshi");
obj4.put("location", "Ranchi");
obj4.put("Profession", "HtlMgmt");
obj4.put("number", 4);
BasicDBObject obj5 = new BasicDBObject();
obj5.put("name", "Ziva");
obj5.put("location", "Ranchi");
obj5.put("Profession", "Player");
obj5.put("number", 5);
My query:
BasicDBObject gtquery = new BasicDBObject();
gtquery.put("number",new BasicDBObject("$gt",3).append("$lt",5));
DBCursor cursor4 = col.find(gtquery);
while(cursor4.hasNext()){
System.out.println(cursor.next());
}
Can anyone please help me out regarding this exception...
To get the range, say 3 < number < 5, change your query to:
BasicDBObject gtquery = new BasicDBObject("number",
new BasicDBObject("$gt", 3).append("$lt", 5)
);
DBCursor cur = col.find(gtquery);
try {
while (cur.hasNext()) {
System.out.println(cur.next());
}
} finally {
cur.close();
}
Related
Document query = new Document();
query.put("firstName", "abc");
query.put("firstName", "xyz");
Here,"abc" is overrided by the "xyz".So,in the query I'm getting only one value i.e,xyz.I don't know,why the query getting overrided.can u please help me out...
My code:
MongoClient mongo = new MongoClient("localhost",27017);
MongoDatabase db = mongo.getDatabase("sample");
MongoCollection<Document> coll = db.getCollection("users");
Document query = new Document();
query.put("firstName", "abc");
query.put("firstName", "xyz");
Document docStatus =new Document("$or",query );
try (MongoCursor<Document> cursor = coll.find(query).iterator()) {
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
}
The arguments to the $or operator are a List, therefore you are just contructing a List of Document:
Document query = new Document(
"$or", Arrays.asList(
new Document("firstname", "abc"),
new Document("firstname", "xyz")
)
)
But really, when you want an $or condition on the same property, use $in instead. Which is of course another List but just of values:
Document query = new Document(
"firstname",
new Document(
"$in", Arrays.asList("abc","xyz")
)
)
Which is much shorter syntax for the selection of "either" value on the same document property.
You need to construct your query as below :
DBObject clause1 = new BasicDBObject("firstName", "abc");
DBObject clause2 = new BasicDBObject("firstName", "xyz");
BasicDBList or = new BasicDBList();
or.add(clause1);
or.add(clause2);
DBObject query = new BasicDBObject("$or", or);
BasicDBList orList = new BasicDBList();
orList.add(new BasicDBObject("FirstName","xxx"));
orList.add(new BasicDBObject("LastName","yyy"));
BasicDBObject dbObj = new BasicDBObject("$or",orList);
I am trying to do a bulk upsert, but am having problems to figure out how to do it. This does not work:
BasicDBObject filter = new BasicDBObject();
BasicDBObject update = new BasicDBObject("$set", list);
UpdateOptions options = new UpdateOptions().upsert(true);
collection.updateMany(filter, update, options);
Exception in thread "main" com.mongodb.MongoWriteException: Modifiers operate on fields but we found a Array instead.
Any examples would just be great!
UpsertMany items in one roundtrip
This is what I meant:
public static BulkWriteResult upsertAll(MongoCollection<Document> coll, List<Document> docs, String keyTag) {
List<UpdateOneModel<Document>> requests = new ArrayList<UpdateOneModel<Document>>();
UpdateOptions opt = new UpdateOptions().upsert(true);
for (Document doc : docs ) {
BasicDBObject filter = new BasicDBObject(keyTag, doc.get(keyTag));
BasicDBObject action = new BasicDBObject("$set", doc);
requests.add(new UpdateOneModel<Document>(filter, action, opt));
}
return coll.bulkWrite(requests);
}
You can perform bulk upsert using below code :
MongoClient mongo = new MongoClient("localhost", 27017);
DB db = (DB) mongo.getDB("testDB");
DBCollection collection = db.getCollection("collection");
BasicDBObject obj = new BasicDBObject();
obj.append("$set", new BasicDBObject("my_field", dbList));
BasicDBList dbList = new BasicDBList();
dbList.add(1);
dbList.add(2);
dbList.add(3);
BulkWriteOperation bwo = collection.initializeUnorderedBulkOperation();
bwo.find(new BasicDBObject()).upsert().update(obj);
bwo.execute();
For more details you can check : http://www.journaldev.com/6324/mongodb-upsert-example-using-mongo-shell-and-java-driver
This might work
db.collection.update({},{$set : {"my_field":[1, 2, 3]}},false,true)
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());
}
I have the document structured as shown
I would like to get a collection of moduleDataItems which has version say more than 0.
This is my attempt :
Query qu = Query.query(Criteria.where("appKey")
.is("MOCK_APP").and("modules._id")
.is("APP_1_MOD_1")
.and("modules.moduleDataItems.version")
.gt(0));
List<DataItem> dList = mongoTemplate.find(qu,
DataItem.class,
ApplicationConstants.MONGO_APPLICATION_COLLECTION_NAME);
I m pretty sure I'm not doing the right thing. I do not get any DataItem in the result.
The classes represent the json structure.
Any help is appreciated.
Thanks
Finally solved it using this -
DBObject unwindParam = new BasicDBObject("$unwind","$dataItems");
DBObject matchParam = new BasicDBObject("$match",
new BasicDBObject("dataItems.version",
new BasicDBObject("$gt",requestedModule.getVersion())));
DBObject fields = new BasicDBObject("dataItems", 1);
DBObject projectParam = new BasicDBObject("$project", fields);
AggregationOutput output = mongoTemplate.getCollection(
"appModules").aggregate(
unwindParam, matchParam,projectParam);
CommandResult updatedData = output.getCommandResult();
BasicDBList resList = (BasicDBList) updatedData.get("result");
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.