Get 2 documents in 1 MongoDB call - node.js

I am using MongoDB and Mongoose to retrieve documents from the database.
I have two IDs and I want to get the corresponding documents. I use
Collection.findById(id1).then(doc1 => {
if (doc1) {
Collection.findById(id2).then(doc2 => {
if (doc2) {
Is it possible to do this in a single call?
I am wondering if it can be done with
{doc1, doc2} = Collection.find({ _id: $in: [id1, id2] });
and if this is better than my original approach.

You can use mongoDB $in operator to retrieve multiple documents, the syntax is
db.inventory.find( { id: { $in: [ 5, 15 ] } } )

Related

Unable to select specific field for MongoDB find operation

I am trying to select only one field from a mongo document and print the value for it. I found this answer https://stackoverflow.com/a/25589150 which showed how we can achieve this. Below I have tried doing the same yet the entire document ends up getting printed.
const mongoHost =
'somemongourl'
const mongodb = require('mongodb');
const { MongoClient } = mongodb;
MongoClient.connect(
mongoHost,
{ useNewUrlParser: true },
async (error, client) => {
if (error) {
return console.log('Unable to connect to database!');
}
const db = client.db('cartDatabase');
const values = await db
.collection('cart')
.find({ customer_key: 'c_1' }, { customer_key: 1, _id: 0 })
.toArray();
console.log(values);
}
);
This is the output for example I got :-
[
{
_id: new ObjectId("611b7d1a848f7e6daba69014"),
customer_key: 'c_1',
products: [ [Object] ],
coupon: '',
discount: 0,
vat: 0,
cart_total: 999.5,
cart_subtotal: 999.5
}
]
This is what I was expecting -
[
{
customer_key: 'c_1'
}
]
The standard Node.js MongoDB driver requires a top-level projection property for the options parameter if you wish to project your documents. This would result in the second parameter of your find() call looking like this:
{ projection: { customer_key: 1, _id: 0 } }
This is indicated in the Node.js MongoDB driver API documentation, which is notably not a 1-to-1 match with the MongoDB shell API.
As of the time of this answer, you could find the collection.find() reference here. This reference shows the following method signature (again as of when this answer was written):
find(filter: Filter<WithId<TSchema>>, options?: FindOptions<Document>)
Following the FindOptions parameter takes us to this reference page, which details the various top-level options properties available for the find() method. Among these is the projection property in question.
In short, don't use the normal MongoDB documentation as a reference for your programming language's MongoDB driver API. There will often be disconnects between the two.

mongodb multiple find by multiple conditions and one result nodejs

i have a collection for users transactions. i want to use a query by three id of users to get last transaction for each one. and i don't want to use a loop to do a query per user.
i used this:
const items = await db
.collection("transactions")
.find({ user: users[1] , user: users[2], user: users[3] })
.limit(3)
.sort({ $natural: -1 })
.toArray();
but it doesn't contain one result per condition because i know i'm doing it wrong.
i use:
const MongoClient = require("mongodb").MongoClient;
how should i do that?
thanks.
You probably need to do an aggregation using $group and $last.
https://docs.mongodb.com/manual/reference/operator/aggregation/group/#examples
db.collection("transactions").aggregate( [
{
$group: {
_id: user,
txnId: { $last: "$_id" }
}
}
] ).toArray();
This answer might also help you: https://stackoverflow.com/a/32134655/1742298

how can i use value of field in mongoose aggregation? (nodejs)

how can i use value of field in mongoose aggregation?
i tried with latest version of mongodb, mongoose.
Group.find({name:'1'},function(err,groups){
groups.forEach(function(g){
result=await People.countDocuments({group:g._id})
});
});
I already checked that 'result' of this code is 3, 5, 2
i want to use aggregate
Group.aggregate()
.project({_id:true,name:true})
.addFields({numOfPeople: await People.countDocuments({group:this._id})});
output
[{name:'1',numOfPeople:0},
{name:'2',numOfPeople:0},
{name:'3',numOfPeople:0}]
expected
[{name:'1',numOfPeople:3},
{name:'2',numOfPeople:5},
{name:'3',numOfPeople:2}]
You have to use group by
db.groups.aggregate(
[
{
$group : {
_id : "$name",
numOfPeople: { $sum: 1 }
}
}
]
);

Mongoose - Find with and array

I have an array of objects : userNames , that contains
[
{
name:"alice"
},
{
name:"jhon"
}
]
and I have collection Users , I want to find users that theirs names are in userNames array without forEach ...
You can use mongo $in operator to search by array values. Example:
const users = userNames.map(user => user.name);
User.find({ name: { $in: users } }).then(users =>
console.log("There you are: ", users)
);

push array in array field in mongodb [duplicate]

This question already has answers here:
Push items into mongo array via mongoose
(11 answers)
Closed 4 years ago.
I have an array called students in a schema called Course. I created a route that allows me to add students to this array using a student's ObjectID like so:
router.put('/addStudent/:courseID', function (req, res) {
Course.findOneAndUpdate({courseID: req.params.courseID}, {$push: {students: req.body.students}})
.populate('students')
.exec(function (err, course) {
if (err) return res.status(500).send("There was a problem adding this information to the database");
res.status(201).send(course);
})
});
When I try making a PUT request to my endpoint with the following JSON body:
{
"students":["5b1f06cafa355c2d187c344f"]
}
Nothing happens at all, it just sends me back the course with the student ID not added. How do I make it so I could add more student IDs to the array? I don't want it to replace the array with a student ID, I want to keep adding more as I make more requests.
Thanks!
You need to use $each with $push
Course.findOneAndUpdate(
{ courseID: req.params.courseID },
{ $push: { students: { $each: req.body.students } } }
)
Course.findOneAndUpdate(
{ courseID: req.params.courseID },
{ $addToSet: { students: { $each: req.body.students } } }
)
put request will update your db and findOneAndUpdate method from mongoose is also for updating you current item, you need to use post request and save method in mongoose instead if you want create a new item.
You can Try this:
Course.findOneAndUpdate(
{ courseID: req.params.courseID },
{ $push: {
students: req.body.students
}}, options, function(err, values){
});

Resources