I have 2 collections namely eventPart and Participants.
eventPart:{
{
"_id" : ObjectId("5b62676ba5419449046a26c4"),
"rollNo" : "15K21A0528",
"eventName" : "Ebullienza",
"team" : 68,
"__v" : 0
},{
"_id" : ObjectId("5b62676ba5419449046a26c5"),
"rollNo" : "15G11A0518",
"eventName" : "Ebullienza",
"team" : 68,
"__v" : 0}
}
Participants : {
{
"_id" : ObjectId("5b62626d9306a610e36aca95"),
"rollNo" : "15S11A0528",
"name" : "Pavan Boro",
"email" : "pavan#gmail.com",
"mobile" : NumberLong(6700332950),
"branch" : "CSE",
"section" : "A",
"year" : 4
}, {
"_id" : ObjectId("5b62633d9306a610e36acae1"),
"rollNo" : "15S11A0518",
"name" : "Manoj",
"email" : "manoj#gmail.com",
"mobile" : NumberLong(9700332910),
"branch" : "CSE",
"section" : "A",
"year" : 4
}}
I want to query the database with eventName in eventPart along with data in Participant collection.
Ex:
With eventName : 'Ebullienza'
I want to fetch all the details that is related to eventName: 'Ebullienza' in Participants collection.
I have tried collecting the rollNo from eventPart and using it for in Participants collection.
But I get stuck in collecting the rollNo in array
var rollNumber = new Array();
EventPart.find({'eventName':'Ebullineza'}).then(function(a){
a.forEach(function(roll){
rollNumber.push(roll.rollNo);
});
});
console.log(rollNumber); // prints [] - empty array
rollNumber is printed as [].
I think there could be a more efficient way of query 2 collections in mongoose.
Thanks.
use $lookup
db.eventPart.aggregate([
{ "$match": { "eventName": "Ebullienza" } },
{
"$lookup": {
"from": "Participants",
"localField": "rollNo",
"foreignField": "rollNo",
"as": "Participants"
}
}
])
print your array in the callback... otherwise he is printed before the end of execution of your find
var rollNumber = new Array();
EventPart.find({'eventName':'Ebullineza'}).then(function(a){
a.forEach(function(roll){
rollNumber.push(roll.rollNo);
});
console.log(rollNumber); // prints [] - empty array
});
Related
FULL DISCLOSURE: I'm a MongoDB noob
I'm dealing with a legacy DB structure. A part of my MongoDB looks like this currently:
Events (_id, name (string), ...)
Orders (_id, eventId (as string), products (array of {prodIdentifier (string), quantity (number)}), customer_ID (string), signee (string), sign_time (date), ...)
Products (_id, prodIdentifier (string), price (number), sku (string), ...)
The relations are as follows:
Event 1..N Orders (via eventId)
Orders 1..N Products (via products array)
I need to query in a way that given an eventId, I return
Order ID Customer Name (can be a cascade request / premeditated
by frontend), Product SKU, Product Name, Quantity,
Value (quantity * price), Signee Name, Sign time
Mind that, my interface requires filters and sorts on all of the above fields along with limit and offset for pagination, to reduce query time, fast UI, etc.
I could use populate on orders, but how am I supposed to honor the limit and offset via mongoose then. I'm wondering if I should make a view, in which case how should I flatten it to send/receive a list that honors the limit and offset.
Or will it have to be a very manual, step-by-step build of the resulting list?
UPDATE:
Sample data in the DB:
Event Object:
{
"_id" : ObjectId("6218b9266487367ba1c20258"),
"name" : "XYZ",
"createdAt" : ISODate("2022-02-03T13:25:43.814+0000"),
"updatedAt" : ISODate("2022-02-14T09:34:47.819+0000"),
...
}
Order(s):
[
{
"_id" : ObjectId("613ae653d0112f6b49fdd437"),
"orderItems" : [
{
"quantity" : NumberInt(2),
"productCode" : "VEO001",
},
{
"quantity" : NumberInt(2),
"productCode" : "VEO002",
},
{
"quantity" : NumberInt(1),
"productCode" : "VEO003",
}
],
"orderCode" : "1000",
"customerCode" : "Customer 1",
"createdAt" : ISODate("2021-09-10T05:00:03.496+0000"),
"updatedAt" : ISODate("2022-02-08T10:06:42.255+0000"),
"eventId" : "6218b9266487367ba1c20258"
}
]
Products:
[
{
"_id" : ObjectId("604206685f25b8560a1cd48d"),
"Product name" : "ABC",
"createdAt" : ISODate("2021-03-05T10:22:32.085+0000"),
"tag" : "VEO001",
"updatedAt" : ISODate("2022-03-28T07:29:21.939+0000"),
"Product Price" : NumberInt(0),
"photo" : {
"_id" : ObjectId("6042071a5f25b8560a1cd4a9"),
"key" : "e8c9a085-4e8d-4ac4-84e9-bb0a83a59145",
"name" : "Screenshot 2021-03-05 at 11.24.50.png"
},
"name" : "ABC",
"_costprice" : NumberInt(12),
"_sku" : "SKUVEO001",
},
{
"_id" : ObjectId("604206685f25b8560a1cd48a"),
"Product name" : "DEF",
"createdAt" : ISODate("2021-03-05T10:22:32.085+0000"),
"tag" : "VEO002",
"updatedAt" : ISODate("2022-03-28T07:29:21.939+0000"),
"Product Price" : NumberInt(0),
"photo" : {
"_id" : ObjectId("6042071a5f25b8560a1cd4a9"),
"key" : "e8c9a085-4e8d-4ac4-84e9-bb0a83a59145",
"name" : "Screenshot 2021-03-05 at 11.24.50.png"
},
"name" : "DEF",
"_costprice" : NumberInt(13),
"_sku" : "SKUVEO002",
},
{
"_id" : ObjectId("604206685f25b8560a1cd48a"),
"Product name" : "GHI",
"createdAt" : ISODate("2021-03-05T10:22:32.085+0000"),
"tag" : "VEO003",
"updatedAt" : ISODate("2022-03-28T07:29:21.939+0000"),
"Product Price" : NumberInt(0),
"photo" : {
"_id" : ObjectId("6042071a5f25b8560a1cd4a9"),
"key" : "e8c9a085-4e8d-4ac4-84e9-bb0a83a59145",
"name" : "Screenshot 2021-03-05 at 11.24.50.png"
},
"name" : "GHI",
"_costprice" : NumberInt(13),
"_sku" : "SKUVEO003",
},
]
Expected output:
You can do something like:
db.orders.aggregate([
{$match: {eventId: "6218b9266487367ba1c20258"}},
{
$lookup: {
from: "products",
localField: "orderItems.productCode",
foreignField: "tag",
as: "orderItemsB"
}
},
{
"$addFields": {
"orderItems": {
"$map": {
"input": "$orderItemsB",
"in": {
"$mergeObjects": [
"$$this",
{
"$arrayElemAt": [
"$orderItems",
{"$indexOfArray": ["$orderItems.productCode", "$$this.tag"]}
]
}
]
}
}
},
orderItemsB: 0
}
},
{
$unset: "orderItemsB"
},
{
$lookup: {
from: "events",
let: {eventId: "$eventId"},
pipeline: [
{
$match: {$expr: {$eq: [{$toString: "$_id"}, "$$eventId"]}}
}
],
as: "event"
}
},
{
$set: {event: {"$arrayElemAt": ["$event", 0]}}
},
{$unwind: "$orderItems"}
])
As you can see on this playground example. This will give you a document for each product of the order with all the data.
Unable to retrieve the list of previous one-year records from today Including null dates in node MongoDB from Contacts collection.
Sample Collection:
{
"_id" : ObjectId("5cb6a9ee8f145b97daf7181b"),
"Name" : "David",
"Age" : "25",
"JoiningDate" : 2019-06-01T06:18:22.359+00:00
}
{
"_id" : ObjectId("5cb3a9ee8f1d1b75daf7181b"),
"Name" : "Smith",
"Age" : "28",
"JoiningDate" : 2019-12-01T06:35:22.865+00:00
}
{
"_id" : ObjectId("5cb3r4ee8f1d1b75daf7181b"),
"Name" : "Peter",
"Age" : "23",
"JoiningDate" : null
}
{
"_id" : ObjectId("5cb4w7ee8f1d1b75daf7181b"),
"Name" : "Maria",
"Age" : "23"
}
{
"_id" : ObjectId("5cb9a9ee8f1d1b24daf7181b"),
"Name" : "Alicia",
"Age" : "24",
"JoiningDate" : 2018-06-01T06:18:22.109+00:00
}
My Code is:
var collection = db.collection('Contacts');
var fromDate = new Date(Date.now() - 365*24*60*60 * 1000);
var data = collection.find({ $or: [{"JoiningDate":{$gt: fromDate}}, {"JoiningDate":{$eq: ''}} ]} );
What wrong I am doing, please correct me!
As undefined,null and someval have different meanings, your query needs to cover all of these cases in order to retrieve all the data.
Use this query which utilises some basic boolean logic to achieve this:
db.getCollection('test').find(
{
$or: [
{"JoiningDate": {$gt: fromDate}},
{"JoiningDate": {$eq: null}},
{"JoiningDate": {$exists: false}}
]
})
{
"_id" : ObjectId("5b8d1ecbb745685c31ad8603"),
"name" : "abc",
"email" : "abc#gmail.com",
"projectDetails" : [
{
"technologies" : [
"abc",
"abc"
],
"_id" : ObjectId("5b8d1ecbb745685c31ad8604"),
"projectName" : "abc",
"projectDescription" : "abc",
"manager" : "abc",
"mentor" : "abc"
}
],
"__v" : 0
}
Here, projectDetails is an array of objects. I want to update the element "projectName" in projectDetails. How do I write a PUT request for the same in Postman?
Try below query
db.users.update({ "email" : "abc#gmail.com","projectDetails._id":ObjectId("5b8d1ecbb745685c31ad8604")},{ $set: { "projectDetails.$.projectName" : "test" } })
Your url should be like this
http://localhost:3000/project/5b8d1ecbb745685c31ad8604
Your put request as mentioned below
router.route("/updateProject",function(req,res){
var id = req.query.project_id; // Check syntax for framework you are using
});
I have a schema in which it has some fields..
i am not able to find query for this, i tried $group but was not able to find results
collection: tasks
{
"_id" : ObjectId("5a475ee4b342fa03e71192bd"),
"title" : "Some Title",
"assignedUsers" : [
{
"_id" : ObjectId("5a47386ee4788102e530f60d"),
"name" : "Sam",
"status" : "Unconfirmed"
},
{
"_id" : ObjectId("5a473878e4788102e530f60f"),
"name" : "Ricky",
"status" : "Rejected"
}
{
"_id" : ObjectId("5a47388be4788102e530f611"),
"name" : "Niel",
"status" : "Unconfirmed"
},
{
"_id" : ObjectId("5a47388be4788102e530f611"),
"name" : "ABC",
"status" : "Unconfirmed"
},
{
"_id" : ObjectId("5a473892e4788102e530f612"),
"name" : "Rocky",
"status" : "Rejected"
}
]
}
Result should contain
Unconfirmed=3
Rejected=2
Thanks
Use below query,
db.coll3.aggregate([{
$unwind: '$assignedUsers'
}, {
$group: {
_id: '$assignedUsers.status',
'count': {
$sum: 1
}
}
}
])
If you want to query against a particular document make sure, you use a $match as first stage and then use the other 2 $unwind and $group.
You would get result as
{ "_id" : "Rejected", "count" : 2 }
{ "_id" : "Unconfirmed", "count" : 3 }
Hope this helps.
I am new to mongoose, I am facing a problem while trying to fetch some data using aggregate query.
One part of my auction schema is:
"_id" : ObjectId("56c58be1faaa402c0d4ae66f"),
"auction_name" : "Auction2",
"auction_start_datetime" : ISODate("2016-02-18T09:30:00.000Z"),
"auction_end_datetime" : ISODate("2016-02-22T09:00:00.000Z"),
"auction_status" : "active",
"auction_series" : "GA-06-C",
"auction_reserve_price" : 1000,
"auction_increment_amount" : 200,
"fancy_numbers" : [
{
"number_end_datetime" : ISODate("2016-02-22T09:00:00.000Z"),
"number_start_datetime" : ISODate("2016-02-18T09:30:00.000Z"),
"increment_amount" : 200,
"reserve_price" : 1000,
"number" : 5000,
"_id" : ObjectId("56c58da3faaa402c0d4ae739"),
"bid_users" : [
{
"user_id" : "56c416a599ad7c9c1611b90b",
"bid_amount" : 7200,
"bid_time" : ISODate("2016-02-18T11:58:53.025Z"),
"user_name" : "amit#mailinator.com",
"_id" : ObjectId("56c5aec4acebf3b4061a645e")
},
{
"user_id" : "56c172dc302a2c90179c7fd1",
"bid_amount" : 15400,
"bid_time" : ISODate("2016-02-19T10:38:43.506Z"),
"user_name" : "rbidder#mailinator.com",
"_id" : ObjectId("56c5afe0d2baef7020ede1b6")
},
{
"user_id" : "56c477afb27a7ed824c54427",
"bid_amount" : 2800,
"bid_time" : ISODate("2016-02-18T11:56:58.830Z"),
"user_name" : "bidder2#mailinator.com",
"_id" : ObjectId("56c5b18a78c3fb340a8c6d75")
},
{
"user_id" : "56c5b17378c3fb340a8c6d73",
"bid_amount" : 5600,
"bid_time" : ISODate("2016-02-18T11:58:34.616Z"),
"user_name" : "bidder3#mailinator.com",
"_id" : ObjectId("56c5b1d778c3fb340a8c6d78")
}
]
}
]
Here, fancy_number is an array under auction collection and bid_users is an array under each fancy_number.
I have the user_id, I want to query and get only the bid_user records in which he is the highest bidder.
For example:
There are 3 users bidded 200,300,400 respectively, I want to get the
record (i.e number and amount) only if this particular user bid is 400
(highest). where ill be passing the user_id
The aggregate query which I wrote is:
var ObjectID = require('mongodb').ObjectID;
tempId = new ObjectID(req.body.aId);
auctionModel.aggregate({$match: {'_id': tempId}},
{$unwind: '$fancy_numbers'},
{$unwind:"$fancy_numbers.bid_users"},
{$group: {'_id':"$fancy_numbers.number" , maxBid: { $max: '$fancy_numbers.bid_users.bid_amount'}}},
function(err, bidData){
if(err){
console.log('Error :' + err);
}
else if(bidData) {
console.log(bidData);
}
});
Somehow this query is not working, its only giving records of max bid and number. I want records only if he is the highest bidder.
If I catch you correctly, please try to do it through $sort, and $limit to retrieve the highest bidder as below
auctionModel.aggregate(.aggregate([
{$match: {'_id': '123'}},
{$unwind: '$fancy_numbers'},
{$unwind: '$fancy_numbers.bid_users'},
{$sort: {bid_amount: 1}},
{$limit: 1}]);