Mongoose query for ID using an array - node.js

I want to query MongoDB using Mongoose with an array of objectIDs. I am not sure how to do this and also get back the 'name' property that is on the root of each document. I've looked online and can't seem to get it working. Below are two things I have tried that might be close but don't work.
{ _id: {
$in : ['5d193a4826540f7a89757f1d']
}
}
{ "name" : {
id: {
$in : ['5d193a4826540f7a89757f1d', '5d8c104d0f867b753d1f506c']
}
}}

First make ObjectIds from your strings:
const ids = ['5d193a4826540f7a89757f1d', '5d8c104d0f867b753d1f506c'];
const queryIds = ids.map(item => ObjectId(item));
Then find needed documents of your collection and set name: 1 to get only name (and _id by default):
collection.find({"_id": {$in : queryIds}}, {name: 1});

Related

Delete whole document for matching objectId in array of objects - MongoDB

The structure of my document looks like this in MongoDB :-
{
_id : "7464bbuiecdhbjdje"
client : "MJMK"
users : [
{_id : "1234" , name : "first user"}
]
}
I would like to remove the whole document for matching users._id. In this case, for a user with _id 1234,the whole document needs to be removed. I have been unable to find any efficient function that does this in Node using mongoose. Thanks for your help.
You want to use deleteMany.
This will delete all documents containing the matches query, in this case a user with matching _id in the users array. Our query will be utilizing Mongo's dot notation to access the array like so:
Model.deleteMany({ 'users._id': "1234" })
From the shell following works. Isn't it possible to do the same in node?
db.collectionname.find({ "users": { $elemMatch: { "_id": "1234" } } })
db.collectionname.remove({ "users": { $elemMatch: { "_id": "1234" } } })
Try this:
db.collectionName.remove({"users._id":{_id:"1234"}})

how to create user defined id in mongodb rather then _id

I have a schema to add the book details i wanted to maintain a user defined id called book_id rather than mongodb _id ,
To do that i was making a service call to find the total number documents in the collection and was increment the response by 1 and then assign to book_id
Is there a way to do it only in the server side like we use auto-increment in MySQL
you can define your own _id pattern. also you can add incremental values to _id field of a mongodb collection. but you can't use any field instead of _id. because mongodb cares _id for preventing duplication. mongodb's approach is different any rdbms. but if you want to use book_id, you can use as a field. but a mongodb collection always have _id field.
for your answer, you can read this document.
also in here you can find official mongodb sequence/auto-increment information.
you can apply this code on mongo shell.
db.book_counters.insert(
{
book_id: "bookid",
seq: 0
}
)
function getNextSequence(book) {
var ret = db.book_counters.findAndModify(
{
query: { book_id: book },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
db.book.insert(
{
book_id: getNextSequence("bookid"),
book: "Harry Potter"
}
)
db.book.insert(
{
book_id: getNextSequence("bookid"),
book: "LOTR"
}
)

Defining a map with ObjectId key and array of strings as value in mongoose schema

I'm facing a problem while creating Mongoose schema for my DB. I want to create a map with a objectId as key and an array of string values as its value. The closest that I can get is:
var schema = new Schema({
map: [{myId: {type:mongoose.Schema.Types.ObjectId, ref: 'MyOtherCollection'}, values: [String]}]
});
But somehow this is not working for me. When I perform an update with {upsert: true}, it is not correctly populating the key: value in the map. In fact, I'm not even sure if I have declared the schema correctly.
Can anyone tell me if the schema is correct ? Also, How can I perform an update with {upsert: true} for this schema?
Also, if above is not correct and can;t be achieved then how can I model my requirement by some other way. My use case is I want to keep a list of values for a given objectId. I don't want any duplicates entries with same key, that's why picked map.
Please suggest if the approach is correct or should this be modelled some other way?
Update:
Based on the answer by #phillee and this, I'm just wondering can we modify the schema mentioned in the accepted answer of the mentioned thread like this:
{
"_id" : ObjectId("4f9519d6684c8b1c9e72e367"),
... // other fields
"myId" : {
"4f9519d6684c8b1c9e73e367" : ["a","b","c"],
"4f9519d6684c8b1c9e73e369" : ["a","b"]
}
}
Schema will be something like:
var schema = new Schema({
myId: {String: [String]}
});
If yes, how can I change my { upsert:true } condition accordingly ? Also, complexity wise will it be more simpler/complex compared to the original schema mentioned in the thread?
I'd suggest changing the schema so you have one entry per myId,
var schema = new Schema({
myId : {type:mongoose.Schema.Types.ObjectId, ref: 'MyOtherCollection'},
values : [String]
})
If you want to update/upsert values,
Model.update({ myId : myId }, { $set : { values : newValues } }, { upsert : true })

Insert document with nested ObjectId

I am trying to insert a document into my mongodb that looks like this:
_id : ObjectId(<id>)
players : {
ObjectId(<id>) {
entry : 'foo'
}
}
However, I can't form JSON in node with an ObjectId as a key. What's the best practice for this? Thanks!
According to the MongoDB documentation:
Field names are strings.
So you can't use ObjectId's as keys, but you can use their string representation:
var playersObj = {};
playersObj[ObjectId()] = { entry : 'foo' }; // this will stringify the ObjectId
var document = {
_id : ObjectId(),
players : playersObj
};

MongoDB _id is convert to ObjectID automatically, but sometime it is not.

I am using a wrapper called mongoskin to access mongoDB. mongoskin is a simple wrapper around mongoDB javascript api.
But when I write to mongoDB, sometimes _id is converted to ObjectID, sometime is it not. The different behavior causes many problem when I have to compare _id. For example:
The following documents in company collection, "creator" is not converted to ObjectID, but item in "clients" is converted to ObjectID automatically.
> db.company.find()
{ "_id" : ObjectId("53d4b452f5b25900005cb998"), "name" : "Default Company Co.", "clients" : [ ObjectId("53d4b452f5b25900005cb999"), ObjectId("53d4b452f5b25900005cb99a") ] }
{ "_id" : ObjectId("53d4b452f5b25900005cb999"), "name" : "client company for 777 - updated", "creator" : "53d4b452f5b25900005cb998", "ssn" : "12-123-1234" }
This is the nodejs code I used to assign _id for "creator"
clientCompany.creator = req.session.user.company_id;
This is the nodejs code I used to assign _id for "clients"
var updateObj = {$addToSet: {clients:resultClient._id} };
// update creator company.clients
creatorCompany.update(updateObj, function(err, result) { ...}
When I console.log "req.session.user.company_id" and "resultClient._id", they both looks like a string type. How come one end up as ObjectID in MongoDB? If there is an auto conversion, how do I make this behavior consistent?
Thanks!
I'm guessing resultClient is the result of a query and req.session.user.company_id a string from your web application? In that case you need to create an ObjectId from the string:
clientCompany.creator = mongoskin.ObjectID(req.session.user.company_id);

Resources