extract only ids from a mongo collection - mongodb

I only need the ids of all documents in a collection in mongodb. I am using meteor. For now, I am using the basic ._each loop but I bet a better way exists but unfortunately its not clicking to me.
Below is my code :
var followedIds = Doubts.find({ch : chId, userId : userId}).fetch();
var d_ids = [];
_.each(followedIds, function(doubt){
d_ids.push(doubt._id)
});

A small change in projection can help you to fetch only _ids from collection:
var followedIds = Doubts.find({ch : chId, userId : userId},
{
fields:{
_id:1
}
}).fetch();
var d_ids = [];
_.each(followedIds, function(doubt){
d_ids.push(doubt._id)
});

You can use _.pluck if you only need the ids.

db.collection_name.find({},{"id":1})
See Docs
{} means all documents
{"id":1} We are only interested in id not other fields.

Related

MongoDB project nested element in _id field

I'm stuck in something very stupid but I can't get out from my own.
MongoDB v4.2 and I have a collection with documents like this:
{"_id":{"A":"***","B":0}}, "some other fields"...
I'm working on top of mongo-c driver and I want to query only the "_id.B" field but I don't know how I can do it. I have tried:
"projection":{"_id.B":1}: It returns me the whole _id object. _id.A & _id.B.
"projection":{"_id.A":0,"All other fields except _id.B":0}: Returns same as above.
"projection":{"_id.A":0,"_id.B":1}: Returns nothing.
How I can do it to get only some object elements when this object is inside the _id field? The first option works for me with objects that aren't inside the _id field but not here.
Best regards, thanks for your time.
Héctor
You can use MongoDB's $project in aggregation to do this. You can also use $addFields to get _id.B into new field + all other fields in document & finally project _id :0.
Code:
var coll = localDb.GetCollection("yourCollectionName");
var project = new BsonDocument
{
{
"$project",
new BsonDocument
{
{ "_id.B": 1 }
}
}
}
var pipeline = new[] { project };
var result = coll.Aggregate(pipeline);
Test : MongoDB-Playground

Mongodb - return an array of _id of all updated documents

I need to update some documents in one collection, and send an array of the _ids of the updated documents to another collection.
Since update() returns the number of updated items not their ids, I've come up with the following to get the array:
var docsUpdated = [];
var cursor = myCollection.find(<myQuery>);
cursor.forEach(function(doc) {
myCollection.update({_id : doc._id}, <myUpdate>, function(error, response){
docsUpdated.push(doc._id);
});
});
Or I could do:
var docsUpdated = myCollection.distinct("_id", <myQuery>);
myCollection.update(<myQuery>, <myUpdate>, {multi : true});
I'm guessing the second version would be faster because it only calls the database twice. But both seem annoyingly inefficient - is there another way of doing this without multiple database calls? Or am I overcomplicating things?
I think you need the cursor operator ".aggregate()"
db.orders.aggregate([
{ $group: { _id: "$_id"} }
])
something along those lines that returns the results of all the id's in the collection

How to get multiple document using array of MongoDb id?

I have an array of ids and I want to get all document of them at once. For that I am writing but it return 0 records.
How can I search using multiple Ids ?
db.getCollection('feed').find({"_id" : { "$in" : [
"55880c251df42d0466919268","55bf528e69b70ae79be35006" ]}})
I am able to get records by passing single id like
db.getCollection('feed').find({"_id":ObjectId("55880c251df42d0466919268")})
MongoDB is type sensitive, which means 1 is different with '1', so are "55880c251df42d0466919268" and ObjectId("55880c251df42d0466919268"). The later one is in ObjectID type but not str, and also is the default _id type of MongoDB document.
You can find more information about ObjectID here.
Just try:
db.getCollection('feed').find({"_id" : {"$in" : [ObjectId("55880c251df42d0466919268"), ObjectId("55bf528e69b70ae79be35006")]}});
I believe you are missing the ObjectId. Try this:
db.feed.find({
_id: {
$in: [ObjectId("55880c251df42d0466919268"), ObjectId("55bf528e69b70ae79be35006")]
}
});
For finding records of multiple documents you have to use "$in" operator
Although your query is fine, you just need to add ObjectId while finding data for Ids
db.feed.find({
"_id" : {
"$in" :
[ObjectId("55880c251df42d0466919268"),
ObjectId("55bf528e69b70ae79be35006")
]
}
});
Just I have use it, and is working fine:
module.exports.obtenerIncidencias386RangoDias = function (empresas, callback) {
let arraySuc_Ids = empresas.map((empresa)=>empresa.sucursal_id)
incidenciasModel.find({'sucursal_id':{$in:arraySuc_Ids}
}).sort({created_at: 'desc'}).then(
(resp)=> {
callback(resp)}
)
};
where:
empresas = ["5ccc642f9e789820146e9cb0","5ccc642f9e789820146e9bb9"]
The Id's need to be in this format : ObjectId("id").
you can use this to transform your string ID's :
const ObjectId = require('mongodb').ObjectId;
store array list in var and pass that array list to find function
var list=db.collection_name.find()
db.collection_name.find({_id:{$in:list}})
db.getCollection({your_collection_name}).find({
"_id" : {
"$in" :
[({value1}),
({value2})
]
}
})

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.

Query or command to find a Document, given an ObjectID but NOT a collection

So I have a document that has references to foreign ObjectIDs that may point to other documents or collections.
For example this is the pseudo-structure of the document
{
_id: ObjectID(xxxxxxxx),
....
reference: ObjectID(yyyyyyyy)
}
I can't find anything that does not involve providing the collection and given that I don't know for sure on which collection to search, I am wondering if there is a way for me to find the document in the entire database and find the collection ObjectID(yyyyyyyy) belongs to.
The only possible way to do this is by listing every collection in the database and performing a db.collection.find() on each one.
E.g. in the Mongo shell I would do something like
var result = new Array();
var collections = db.getCollectionNames();
for (var i = 0; i < collections.length; i++) {
var found = db.getCollection(collections[i]).findOne({ "_id" : ObjectId("yyyyyyyy") });
if (found) {
result.push(found);
}
}
print(result);
You need to run your query on all collections in your database.
db.getCollectionNames().forEach(function(collection){
db[collection].find({ $or : [
{ _id : ObjectId("535372b537e6210c53005ee5") },
{ reference : ObjectId("535372b537e6210c53005ee5")}]
}).forEach(printjson);
});