MongoDB console: Getting the _id of a cursor object - mongodb

Is it possible to get the _id of a cursor? The following method does not work for me.
> var cursor = db.genre.find({name:"romance"})
> db.genre.find({name:"romance"}, {"_id":1})
{ "_id" : ObjectId("5c03537d7d0db45bee0f64d0") } // output
I just would like the value: ObjectId("5c03537d7d0db45bee0f64d0" to be returned.

Thanks to mickl, the answer is
db.genre.find({name:"romance"}, {"_id":1})[0]._id

Related

How to retrieve values of nested objects in a Mongo DB document using java

I have a document like below:
"application" : "test",
"QA1" : {
"url" : "https://google.co.in",
"db" : {
"userName" : "user",
"password" : "pswd"
}
}
I want to retrieve the value "https://google.co.in" by calling the key "url".
While using the below shell command, I am able to retrieve the value as expected.
db.getCollection('Application_Data').findOne({"application":"test"}).QA1.url
But when I convert it to java code, it is throwing me null pointer exception:
cursor = collection.find(Filters.eq("application","test")).iterator();
while (cursor.hasNext()) {
value=cursor.next().get("QA1.url").toString();
break;
}
I also tried with projection like below to get the required values:
cursor = collection.find(Filters.and(Filters.eq("application","test"))).projection(Projections.fields(Projections.include("QA1.url"),Projections.excludeId())).iterator();
while (cursor.hasNext()) {
System.out.println(cursor.next().get("QA1").toString());
}
This is giving me the output as below:
Document{{url=https://google.co.in}}
It is still not giving me the exact value. Appreciate your help on this.
Mongodb Documents are nested. So say, in your example, when you do cursor.next().get("QA1"), you get the Document under "QA1" property.
So the way to achieve what you want is
cursor.next().get("QA1").get("url"). That, with proper error handling (think exceptions).
A better way to do what you want is to use a mapper like spring-data-mongodb that would map the JSON response of mongodb into a java object for you automatically.
You need to use the Document class's getEmbedded method to extract the nested field's value.
while (cursor.hasNext()) {
Document doc = cursor.next();
System.out.println(doc.toJson());
String urlValue = doc.getEmbedded(Arrays.asList("QA1","url"), String.class);
System.out.println(urlValue); // output below
}
The result is as expected - a string: https://google.co.in

Mongo DB find() query error

I am new to MongoDB. I have a collection called person. I'm trying to get all the records without an _id field with this query:
db.person.find({}{_id:0})
but the error is
syntax error: unexpected {
but if i write
db.person.find()
it works perfectly.
Consider following documents inserted in person collection as
db.person.insert({"name":"abc"})
db.person.insert({"name":"xyz"}
If you want to find exact matching then use query as
db.person.find({"name":"abc"})
this return only matched name documents
If you want all names without _id then use projeciton id query as
db.person.find({},{"_id":0})
which return
{ "name" : "abc" }
{ "name" : "xyz" }
According to Mongodb manual you have little wrong syntax, you forgot to give comma after {}
Try this :
db.person.find({}, { _id: 0 } )

How to check if a portion of an _id from one collection appears in another

I have a collection where the _id is of the form [message_code]-[language_code] and another where the _id is just [message_code]. What I'd like to do is find all documents from the first collection where the message_code portion of the _id does not appear in the second collection.
Example:
> db.colA.find({})
{ "_id" : "TRM1-EN" }
{ "_id" : "TRM1-ES" }
{ "_id" : "TRM2-EN" }
{ "_id" : "TRM2-ES" }
> db.colB.find({})
{ "_id" : "TRM1" }
I want a query that will return TRM2-EN and TRM-ES from colA. Of course in my live data, there are thousands of records in each collection.
According to this question which is trying to do something similar, we have to save the results from a query against colB and use it in an $in condition in a query against colA. In my case, I need to strip the -[language_code] portion before doing this comparison, but I can't find a way to do so.
If all else fails, I'll just create a new field in colA that contains only the message code, but is there a better way do it?
Edit:
Based on Michael's answer, I was able to come up with this solution:
var arr = db.colB.distinct("_id")
var regexs = arr.map(function(elm){
return new RegExp(elm);
})
var result = db.colA.find({_id : {$nin : regexs}}, {_id : true})
Edit:
Upon closer inspection, the above method doesn't work after all. In the end, I just had to add the new field.
Disclaimer: This is a little hack it may not end well.
Get distinct _id using collection.distinct method.
Build a regular expression array using Array.prototype.map()
var arr = db.colB.distinct('_id');
arr.map(function(elm, inx, tab) {
tab[inx] = new RegExp(elm);
});
db.colA.find({ '_id': { '$nin': arr }})
I'd add a new field to colA since you can index it and if you have hundreds of thousands of documents in each collection splitting the strings will be painfully slow.
But if you don't want to do that you could make use of the aggregation framework's $substr operator to extract the [message-code] then do a $match on the result.

MongoDB: Adding a new field based on an existing field using $substr

I have a simple collection like below
> db.test.save({first:"Ab"})
> db.test.find()
{ "_id" : ObjectId("518a1524f635dc8bb092e1ac"), "first" : "Ab" }
I want to add a new field called 'fl' which holds the first letter of the field "first".
I tried this
> db.test.update({},{"$set":{"fl":{"$substr":["$first",0,1]}}})
not okForStorage
But I get the exception "not okForStorage" as you can see.
Any suggestions, workarounds?
Possibly a duplicate of Multiply field by value in Mongodb but here's a workaround:
db.test.find().forEach(function(e) {
e.fi = e.first[0];
db.save(e);
});

Exception : can't convert from BSON type OID to String

I'm newbie to mongo db , so here is the question i'm getting this following error when try to change name to upper case in mongodb thru console.
here is the query :
t.aggregate([{$project:{name:{$toUpper:"$_id"} , _id:0}}])
Also , I have manually inserted all the fields with "_id" as name such as
"_id" : "joe"
thanks in advance
The syntax you have looks correct, so you should try to find the document that isn't a string. In the shell type this:
db.t.find({}).forEach(function(item) { if(typeof item._id !== 'string') { print(item._id); })
That will output any IDs that aren't strings.