MongoDB select where in array of _id? - javascript

is possible in mongo db to select collection's documents like in SQL :
SELECT * FROM collection WHERE _id IN (1,2,3,4);
or if i have a _id array i must select one by one and then recompose the array/object of results?

Easy :)
db.collection.find( { _id : { $in : [1,2,3,4] } } );
taken from: https://www.mongodb.com/docs/manual/reference/operator/query/in/#mongodb-query-op.-in

Because mongodb uses bson and for bson is important attribute types. and because _id is ObjectId you must use like this:
db.collection.find( { _id : { $in : [ObjectId('1'),ObjectId('2')] } } );
and in mongodb compass use like this:
{ "_id" : { $in : [ObjectId('1'),ObjectId('2')] } }
Note: objectId in string has 24 length.

You can try this
var ids = ["5883d387971bb840b7399130","5883d389971bb840b7399131","5883d38a971bb840b7399132"];
var oids = [];
ids.forEach(function(item){
oids.push(new ObjectId(item));
});
.find({ _id: {$in : oids}})

In this code list is the array of ids in user collection
var list = ["5883d387971bb840b7399130","5883d389971bb840b7399131","5883d38a971bb840b7399132"]
.find({ _id: {$in : list}})

if you want to find by user and also by another field like conditionally, you can easily do it like beneath with spread and ternary operator using aggregate and match
const p_id = patient_id;
let fetchingReports = await Reports.aggregate([
...(p_id
? [
{
$match: {
createdBy: mongoose.Types.ObjectId(id),
patient_id: p_id,
},
},
]
: [
{
$match: {
createdBy: mongoose.Types.ObjectId(id),
},
},

Related

How to find all users that have emails in an array in prisma using Typescript?

Hi sorry for the confusing question. Basically, I want to find all the users that have emails that are included in the array.
For example I have an array:
const arr = ['test#gmail.com', 'test2#gmail.com']
and I have my model
model User {
id Int
username String
name String
email String
}
I want to do something like
const data = await prisma.user.findMany({
where : {
email: in arr
},
select : {
id: true
}
});
I have been trying to find a workaround for this for the longest time.
This is the syntax for the in operator in Prisma.
const arr = ['test#gmail.com', 'test2#gmail.com']
const data = await prisma.user.findMany({
where : {
email: {in: arr}
},
select : {
id: true
}
});
You can read more in the Prima Client Reference in the docs.

MongoDb Node.js Querying Nested Objects not working?

I need to query for 2 dynamic properties using the node.js driver for mongodb.
Here's the data structure:
{
"_id":"123456",
"dateAdded":"2017-09-20T08:36:40.325Z",
"followers":{
"name1":{
"followedOn":"2017-09-20T08:36:40.325Z",
"unfollowedOn":null
},
"name2":{
"followedOn":"2017-09-20T08:36:40.325Z",
"unfollowedOn":null
}
}
}
Here's my code:
//Working but not dynamic
collections.find({ '_id': '123456', 'followers.name1': { $exists: false } })
//My failed attempt at making it dynamic
const id = "123456"
const username = "name1"
let query = {}
query['followers.'+username] = { $exists: true }
collections.find( { "_id": id, query }
Note that this is not a duplicate of "how to make a dynamic key in an object literal". The .find() method of node.js mongodb driver does not accept object literals. I can't find documentation of what it accepts exactly.
Your _id property needs to be within query object, not separate.
Here's how to do it:
let query = { _id: id };
query['followers.'+username] = { $exists: true }
collections.find(query);

Referring to ObjectIDs directly in MongoDB works, but not in Mongoose

The first code snippet achieves the desired effect:
//in mongodb console:
db.collection.update({"username":"name"}, {$pull : { "task" : { "_id" : ObjectId("55280205702c316b6d79c89c")}}})
Yet this second (seemingly equivalent) code snippet written in Mongoose does not:
//in Mongoose:
var taskID = "55280205702c316b6d79c88c"
var pull = { $pull : {}};
var idObj = {};
idObj["_id"] = taskID;
pull.$pull["task"] = idObj;
collectionModel.update({"username": "name"}, pull) //fails to work since taskID just shows up as a literal string 55280205702c316b6d79c88c instead of ObjectId("55280205702c316b6d79c88c")
Other things I've tried:
making var taskID equal to the string 'ObjectId(\"55280205702c316b6d79c88c\")'
setting var taskID equal to mongoose.Types.ObjectId("55280205702c316b6d79c88c")
How can I achieve the effect in the former code snippet in Mongoose?
Import ObjectId type and use it in your query :
var ObjectId = require('mongoose').Types.ObjectId;
idObj["_id"] = new ObjectId("55280205702c316b6d79c88c");
After you did the $pull operation in mongodb shell and tried the same update operation in Mongoose with the same ObjectId, it didn't work because the task array object element with "_id": ObjectId("55280205702c316b6d79c88c") was removed by the previous mongodb shell operation.
Try first running the same query from Mongoose but with a different and existing taskID which is cast to ObjectId. You could add an extension to the String object as follows:
String.prototype.toObjectId = function() {
var ObjectId = (require("mongoose").Types.ObjectId);
return new ObjectId(this.toString());
};
var taskID = "55280205702c316b6d79c88d".toObjectId(); // a different _id
collectionModel.update(
{ "username": "name" },
{ "$pull" : { "task": { "_id": taskID } } },
function (err, result) {
console.log(result);
}
);

Mongoose - delete subdocument array item

I have this little schema for users:
{
username: String,
contacts: Array
}
So for example some user's contacts will look like this:
{
username: "user",
contacts: [{'id': ObjectId('525.....etc'), 'approved': false}, {'id':ObjectId('534.....etc'), 'approved': true}]
}
Now I need to delete an item from contacts so I do:
model.findByIdAndUpdate(23, {'$pull': {
'contacts':{'id':'525.....etc'}
}});
but seems not working, no errors but it doesn't gets deleted, I just would like to return this document for the user:
{
username: "user",
contacts: [{'id':ObjectId('534.....etc'), 'approved': false}]
}
how to achieve this?
The $pull operator actually just performs the conditions on the array element on which it is operating. It seems that your question might not actually show that you are probably working with an ObjectId value that mongoose creates by default for all array fields.
So you could to your query like this, after importing the ObjectId creation method:
model.findByIdAndUpdate(23, {
'$pull': {
'contacts':{ '_id': new ObjectId(someStringValue) }
}
});
Or in fact you can actually define your "schema" a little better, and mongoose will actually "autocast" the ObjectId for you based on the "type" defined in the schema:
var contactSchema = new Schema({
approved: Boolean
});
var userSchema = new Schema({
username: String,
contacts: [contactSchema]
});
This allows mongoose to "follow the rules" for strictly typed field definitions. So now it knows that you actually have an _id field for each element of the contacts array, and the "type" of that field is actually an ObjectId so it will automatically re-cast "String" values supplied as a true ObjectId.
finaly!
MongoDB:
"imgs" : {"other" : [ {
"crop" : "../uploads/584251f58148e3150fa5c1a7/photo_2016-11-09_21-38-55.jpg",
"origin" : "../uploads/584251f58148e3150fa5c1a7/o-photo_2016-11-09_21-38-55.jpg",
"_id" : ObjectId("58433bdcf75adf27cb1e8608")
}
]
},
router.get('/obj/:id', function(req, res) {
var id = req.params.id;
Model.findOne({'imgs.other._id': id}, function (err, result) {
result.imgs.other.id(id).remove();
result.save();
});

MongoDB and nodejs, find throught list of ids

I have two collections:
users:
{
_id: ObjectId('123...'),
docs: [
ObjectId('512d5793abb900bf3e000002'),
ObjectId('512d5793abb900bf3e000001')
]
}
docs:
{
_id: ObjectId('512d5793abb900bf3e000002'),
name: 'qwe',
...
}
{
_id: ObjectId('512d5793abb900bf3e000001'),
name: 'qwe2',
...
}
I want to get docs from ids. I try this solution, but I get this message:
{ db: { domain: null,
_events: {},
_maxListeners: 10,
databaseName: 'test', ...
Your message looks like a mongodb cursor returned from find by native mongodb driver.
To get actual data you should use toArray function of the cursor:
var ObjectID = require('mongodb').ObjectID;
// you shall wrap each id in ObjectID
var idsProjects = [
ObjectID('512d5793abb900bf3e000002'),
ObjectID('512d5793abb900bf3e000001')
];
collectionProjects.find({
_id: { $in: idsProjects }
},{
_id: -1, // use -1 to skip a field
name: 1
}).toArray(function (err, docs) {
// docs array here contains all queried docs
if (err) throw err;
console.log(docs);
});
But I recommend you to switch from native mongodb driver to some wrapper around it like monk.
If you care about the order of the list, the answer of Mr.Leonid may not work as expected to do.
That's because find gets the docs that have _id equals to any _ids $in the list so the output docs will be ordered by the main order of the collection itself not the order of the input list.
To solve that you can just use the normal findOne with a for loop to the list.
The code will look like:
var ObjectID = require('mongodb').ObjectID;
var idsProjects = [
'512d5793abb900bf3e000002',
'512d5793abb900bf3e000001'
];
let usersList = new Array();
for (let index = 0; index < idsProjects.length; index++) {
const myID = idsProjects[index];
const query = { _id: ObjectID(myID) };
const options = {
projection: {name: 1 };
var user= await collectionProjects.findOne(query,options);
usersList.push(user);
}
// that's it,
// here we have a list of users 'usersList'
//with same order of the input ids' list.
console.log(usersList);

Categories