Mongodb Node.js $lookup with date and $match - node.js

Can anyone help I am using $lookup for join in MongoDB to get all orders where the date is between date "X" and date "Y" and chef_id is "P". something is wrong in "date" part which is not giving data on the dates. but when I use it in single Find query it works fine and gives data between the dates. but it does not give data when I applied with $lookup for join.
Here is my query
Order.aggregate([{
"$lookup": {
"localField": "user_id",
"from": "users",
"foreignField": "_id",
"as": "order_data"
}
},
{
"$match": {
"$and": [
{ "chef_id": mongoose.Types.ObjectId(req.body.chef_id) },
{ "booking_datetime": { $gte: start_time,
$lte: end_time } }
]
}
}
], function(err, gettt) {
if (err) {
res.json({ 'message': "Error", 'status': false, 'data': err });
return false;
} else {
if (gettt.length != 0) {
res.json({ 'message': "Orders Data", 'status': true, 'data': gettt });
} else {
res.json({ 'message': "No Orders for this date", 'status': false, 'data': gettt });
}
}
});
Can anyone help me out.
my collection is here "Order" collection
{
"_id" : ObjectId("5a4256cc3f76bc45065021fc"),
"order_status" : 2,
"total_order_amount" : "160",
"booking_datetime" : ISODate("2017-12-29T23:24:00.000Z"),
"customer_address" : "121/161, South Extension part",
"user_id" : ObjectId("5a3cb4a8a188f2074714f1de"),
"chef_id" : ObjectId("5a390b07f0b3563db59cb3ca"),
"updated_at" : ISODate("2017-12-26T14:03:56.742Z"),
"created_at" : ISODate("2017-12-26T14:03:56.342Z"),
"products" : [
{
"product_id" : "5a3a50fcefc0c972377c3012",
"product_name" : "sweet corn",
"quantity" : "12",
"_id" : ObjectId("5a4256cc3f76bc45065021fd"),
"updated_at" : ISODate("2017-12-26T14:03:56.736Z"),
"created_at" : ISODate("2017-12-26T14:03:56.736Z")
},
{
"product_id" : "5a3a5119efc0c972377c3013",
"product_name" : "chilly paneer",
"quantity" : "10",
"_id" : ObjectId("5a4256cc3f76bc45065021fe"),
"updated_at" : ISODate("2017-12-26T14:03:56.736Z"),
"created_at" : ISODate("2017-12-26T14:03:56.736Z")
},
{
"product_id" : "5a3a512cefc0c972377c3014",
"product_name" : "Gulab jamun",
"quantity" : "20",
"_id" : ObjectId("5a4256cc3f76bc45065021ff"),
"updated_at" : ISODate("2017-12-26T14:03:56.736Z"),
"created_at" : ISODate("2017-12-26T14:03:56.736Z")
},
{
"product_id" : "5a3a50fcefc0c972377c3012",
"product_name" : "ali baba",
"quantity" : "56",
"_id" : ObjectId("5a4256cc3f76bc4506502200"),
"updated_at" : ISODate("2017-12-26T14:03:56.736Z"),
"created_at" : ISODate("2017-12-26T14:03:56.736Z")
}
],
"__v" : 1
and here is my User Collection
{
"_id" : ObjectId("5a623f67eaa08537fe0dba02"),
"salt" : "73824ba53291740e15d26c300c997ce1436ac678299101171af74f4980433285",
"hash" : "8f78291ac737dac15f59f5438033a61de75282a3c671a8d0231406a8374adec140b4cb2dd30b852f05241c6f9900443906fafec22ad58c983dacaed8f9ef4f9039e72b748d9c63d924239aa40372923d824a9cc796079556c8bc5eb0b0f6b17e7fd4c35b8780c870d1b4b819e641e56ce2f88fb0a7fdfbfd91d15921e9b7441a7051523903b43b930f56057852e41ffdbdc044cc09b14ebaac77940576b483d58ff1e18c381d40a143abcd1a180ca208aac6a13eb5c819b97e7e5753bd6fc40fcc1e19b55cb816879b3fedbf187110e84149bad0918672bd2de49bc323a32f04dd0e55aded9a0157fd5eea7db645303eb4cf461e47ca905e1f196618814b88421a3cab9463dac01d5bf6aebcace6e4b1215c3cf07aaae1cac07c94dc28432d223407778f4c6b12b089e09d56a59b1f00084c727f06247c1799c1a8616c74693e2d7057a5026e3c02b9ef73bf867873508575a33fc1e956bd3c704c54e6cc38ffb22e7a04ade70db134ec87e9ed3f43a7273db115127470f8ca5d8def49ba47fe7852cdf0cbd3140b19d5fe358d29eb84519365eea6353fa34c7a6757fbd9ec2ba93eca802f21944da58cd72b5d0d7000f9fd6f231f0668b7e621117a18fcedf977515e181325a9210380e01892891fcc420a67cb5246688eb6e577fccb6d41e719b426fa20c4689af9a9485d0ae0cf026845de8b4f12c7277b9cc506b5e29224",
"email" : "eduardo.llano#geocampo.co",
"firstname" : "Pedro",
"lastname" : "Peez",
"dob" : "1980-01-19",
"phone" : "3185311158",
"gender" : "male",
"latitude" : "4.6936225",
"longitude" : "-74.0730777",
"address" : "Bogota",
"divice_token" : "dcd8cf3ceefc39b8",
"prossing_form" : "1",
"status" : true,
"role" : "chef",
"updated_at" : ISODate("2018-02-01T16:09:27.465Z"),
"created_at" : ISODate("2018-01-19T18:56:39.070Z"),
"products" : [
{
"product_name" : "Producto 1",
"product_price" : "100",
"discount" : "10",
"product_ingredients" : "Pepper",
"product_description" : "Nsjdjd jsjdjdjx",
"minimum_order" : "2",
"tags" : "Indian food",
"status" : "1",
"product_image0" : "https://s3-us-west-2.amazonaws.com/rafahoproject/a47df980-7221-4fde-97cd-977cb3dd1dcf.jpg",
"product_image1" : "https://s3-us-west-2.amazonaws.com/rafahoproject/3a282cae-028c-4d4a-9a22-4c2c43d440f1.jpg",
"product_image2" : "https://s3-us-west-2.amazonaws.com/rafahoproject/1ab4373e-ec63-43fe-9b94-7b85d289c7f9.jpg",
"_id" : ObjectId("5a6602aa135fae732d5ce3d7")
},
{
"product_name" : "Bandeja Paisa",
"product_price" : 100,
"discount" : 20,
"cuisine" : "Continental",
"minimum_order" : 5,
"cooking_time_at_chef_place" : 8,
"cooking_time_at_user_home" : 10,
"tags" : "Bandeja-Paisa,Bandeja,Paisa",
"status" : "1",
"product_image0" : "https://s3-us-west-2.amazonaws.com/rafahoproject/0252161e-0e2a-4682-b7ab-0dce355be794.jpg",
"_id" : ObjectId("5a71d268947536411def9b11")
},
{
"product_name" : "Fritanga",
"product_price" : 200,
"discount" : 30,
"cuisine" : "continental",
"minimum_order" : 6,
"cooking_time_at_chef_place" : 3,
"cooking_time_at_user_home" : 5,
"tags" : "Fritanga,platter-of-grilled-meats",
"status" : "1",
"product_image0" : "https://s3-us-west-2.amazonaws.com/rafahoproject/14c39e2f-4d02-4cd1-8aa7-2f7179b5ea0c.jpg",
"_id" : ObjectId("5a71d3c6947536411def9b12")
},
{
"product_name" : "Dominican Sancocho",
"product_price" : 300,
"discount" : 50,
"cuisine" : "continental",
"minimum_order" : 5,
"cooking_time_at_chef_place" : 1,
"cooking_time_at_user_home" : 2,
"tags" : "Dominican-Sancocho,Dominican,Sancocho",
"status" : "1",
"product_image0" : "https://s3-us-west-2.amazonaws.com/rafahoproject/40a701ff-f868-492d-bee1-d65004fff024.jpg",
"_id" : ObjectId("5a71d4da947536411def9b13")
},
{
"product_name" : "Sudado de Pollo",
"product_price" : 60,
"discount" : 10,
"cuisine" : "Continental",
"minimum_order" : 3,
"cooking_time_at_chef_place" : 3,
"cooking_time_at_user_home" : 2,
"tags" : "Sudado-de-Pollo,Sudado,de-Pollo",
"status" : "1",
"product_image0" : "https://s3-us-west-2.amazonaws.com/rafahoproject/544c2ceb-839b-4263-b482-e2262c228948.jpg",
"_id" : ObjectId("5a71d6e9947536411def9b14")
}
],
"loc" : {
"coordinates" : [
-74.0730777,
4.6936225
],
"type" : "Point"
},
"__v" : 9,
}

Your syntax looks good. I still suspect there is some data type mismatch or erroneous format. I have a similar aggregate which matches a date range, and I use new Date() to convert my strings to date.
if (typeof dateBeginning === "string" && dateBeginning != "" && typeof dateEnding === "string" && dateEnding != "" && dateEnding >= dateBeginning) {
query.date = { $gte: new Date(dateBeginning), $lte: new Date(dateEnding) };
}
Here is an SO question: Date query with ISODate in mongodb doesn't seem to work
which was resolved this way.
Also, Veeram is correct; you should put your $match first. That way, MongoDb will use any indexes on the match fields that are available.

Related

How to find triple conditions in MongoDB

I have database like below.
{
"_id" : ObjectId("628bed8298b81711c01b6ab1"),
"status" : true,
"city" : "Kefar Sava",
"request" : [
{
"deadline" : {
"from" : ISODate("2022-05-03T00:00:00.000+0000"),
"to" : ISODate("2022-05-31T00:00:00.000+0000")
},
"ownerId" : "628c424431884d1c140f56bc",
"type" : "Developer",
"name" : "Apollo",
"status" : "posted",
"_id" : ObjectId("628d496d38360a30a4c39ebd"),
},
{
"deadline" : {
"from" : ISODate("2022-05-03T00:00:00.000+0000"),
"to" : ISODate("2022-06-02T00:00:00.000+0000")
},
"ownerId" : "628c424431884d1c140f56bb",
"type" : "Developer",
"name" : "Apollo",
"status" : "posted",
"_id" : ObjectId("628d4a00a4ec7e12a02e74a3"),
},
],
"date" : ISODate("2022-05-23T20:24:34.052+0000"),
"__v" : NumberInt(0),
}
I want to find by ownerId, type, city and set status to canceled.
I use
const owner = await User.findOneAndUpdate(
{$and: [{city: city, "request.ownerId": ownerId, "request.type": type }]},
{$set: {"request.$.status": "canceled"}},
{new: true})
But I can't find by type. When I change order of that(ownerId and type), then I can't find by ownerId.
Please tell me what's wrong with my code.

Query Mongodb works with the terminal but not with node js

I find myself in front of a problem that I do not know how to solve.
The purpose of the query:
Compare the document of the selection person, and the one who requests the query if the id of the person selected is present in friend then is_friend will be equal to true otherwise it will be equal to false.
I got this query:
users.aggregate({
$match:{
search:/f/
}},{
$lookup:
{from:"users", let:{user:"$_id"}, pipeline:[{
$match:{
$expr:{
$and:[{
$in:["$$user", "$friend.id"]},{
$eq:["$_id", ObjectId("5bd22f28f77cfb1f6ce503ca")]
}]
}
}
},
{$limit:1},
{$project:{email:0, password:0}}
], as:"is_friend"}},{
$project:{name:1, search:1, desc:1, color:1, profil:1, banner:1, date:1, friend:1, is_friend:{
$cond:{
if:{
$eq:[{$arrayElemAt:["$is_friend",0]}, undefined]
},
then: "false",
else:"true"
}
}
}
})
So there is 1 document of users:
{
"_id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"search" : "flarize",
"name" : "flarize",
"email" : "flarize.73#gmail.com",
"password" : "$2a$10$eYeOtEkEUyD7TFkjKvhZOuSSpvBolkL17TrPHuoHhOT8JrsQR0UKW",
"color" : 0,
"profil" : "",
"banner" : "",
"desc" : "",
"date" : 1540501286109,
"friend" : [
{
"id" : ObjectId("5bd19a92da24674fdabd26b6"),
"date" : 1540676931288
},
{
"id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"date" : 1540676931288
}
]
}
When I call this request in the terminal i got this result:
{
"_id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"search" : "flarize",
"name" : "flarize",
"color" : 0,
"profil" : "",
"banner" : "",
"desc" : "",
"date" : 1540501286109,
"friend" : [
{
"id" : ObjectId("5bd19a92da24674fdabd26b6"),
"date" : 1540666689579
},
{
"id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"date" : 1540666689579
}
],
"is_friends" : "true"
}
That's the result I want.
But the node js i got this :
{
"_id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"search" : "flarize",
"name" : "flarize",
"color" : 0,
"profil" : "",
"banner" : "",
"desc" : "",
"date" : 1540501286109,
"friend" : [
{
"id" : ObjectId("5bd19a92da24674fdabd26b6"),
"date" : 1540666689579
},
{
"id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"date" : 1540666689579
}
],
is_friend : {
"_id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"search" : "flarize",
"name" : "flarize",
"color" : 0,
"profil" : "",
"banner" : "",
"desc" : "",
"date" : 1540501286109,
"friend" : [
{
"id" : ObjectId("5bd19a92da24674fdabd26b6"),
"date" : 1540676931288
},
{
"id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"date" : 1540676931288
}
]
}
}
How to solve the problem.
EDIT
mu node js code:
users.aggregate({
$match:{
search:new RegExp(req.body.search, 'i')
}},{
$lookup:
{from:"users", let:{user:"$_id"}, pipeline:[{
$match:{
$expr:{
$and:[{
$in:["$$user", "$friend.id"]},{
$eq:["$_id", new ObjectId(decoded["_id"])]
}]
}
}
},
{$limit:1},
{$project:{email:0, password:0}}
], as:"is_friend"}},{
$project:{name:1, search:1, desc:1, color:1, profil:1, banner:1, date:1, friend:1, is_friend:{
$cond:{
if:{
$eq:[{$arrayElemAt:["$is_friend",0]}, undefined]
},
then: "false",
else:"true"
}
}
}
}).toArray(function(err, result){
if(err) throw err;
ress.send(result);
});
Thank you for helping me

How to fetch particular array elements from object's array in mongo db

I've a row, which contains data like:
{
"_id" : ObjectId("5bcef76b0c9a4c194cf6d0a7"),
"userid" : ObjectId("5bc5ae4355418805b8caabb3"),
"transactionid" : "ch_1DON67EzCa9AoDtY51kialzs",
"adminid" : [
"5b5af339bc69c511816e8a2f",
"5b87948d97b752099c086708"
],
"amount" : 3220,
"ispaid" : true,
"products" : [
{
"productid" : ObjectId("5bceba35003c87043997a1d4"),
"quantity" : 2,
"price" : 200,
"type" : "product",
"isCanceled" : false,
"isDeliverd" : false,
"createdby" : "schooladmin",
"userid" : ObjectId("5b87948d97b752099c086708"),
"isReadyToPickup" : false,
"name" : "The Second Product",
"description" : " "
},
{
"productid" : ObjectId("5bc5b2df55418805b8caabbd"),
"quantity" : 2,
"price" : 100,
"type" : "product",
"isCanceled" : false,
"isDeliverd" : false,
"createdby" : "superadmin",
"userid" : ObjectId("5b5af339bc69c511816e8a2f")
},
{
"productid" : ObjectId("5bc5bc5fe84c3d028aaa269c"),
"quantity" : 2,
"price" : 100,
"type" : "product",
"isCanceled" : false,
"isDeliverd" : false,
"createdby" : "superadmin",
"userid" : ObjectId("5b5af339bc69c511816e8a2f")
}
],
"paymentUsing" : "card",
"cardBrand" : "Visa",
"country" : "US",
"paymentDate" : "2018-10-23T10:26:51.856Z"
}
I want to perform search on products object's all element. And if any of them match, that entire object will be store in array variable.
Suppose, I try to search The Second Product string from name object
of products array. then it would be give me the all element. like
[
{
"productid" : ObjectId("5bceba35003c87043997a1d4"),
"quantity" : 2,
"price" : 200,
"type" : "product",
"isCanceled" : false,
"isDeliverd" : false,
"createdby" : "schooladmin",
"userid" : ObjectId("5b87948d97b752099c086708"),
"isReadyToPickup" : false,
"name" : "The Second Product",
"description" : " "
}
]
And if two or more elements founds then it will return it array accordingly.
Please suggest me the solution.
Thank You in Advance. :)
Something like this:
db.collection.find({products: {$elemMatch: {name:'The Second Product'}}})
Using aggregation pipeline we can get the desired result.
Approach 1:
A simpler approach if we don't have nested arrays
$filter is used within $project to get the desired result
db.collection_name.aggregate([
{
$project: {
products: {
$filter: {
input: "$products",
as: "product",
cond: {
$eq: [
"$$product.name",
"The Second Product"
]
}
}
}
}
}
])
Approach 2:
$unwind to unwind the products array
$match to retrieve the matching documents
$project to project only the required output elements
db.collection_name.aggregate([
{ $unwind: "$products" },
{ $match:{"products.name":"The Second Product"} },
{ $project:{products:1}}
])
Output of the above queries(Approach 1 or Approach 2)
{
"_id" : ObjectId("5bcef76b0c9a4c194cf6d0a7"),
"products" : {
"productid" : ObjectId("5bceba35003c87043997a1d4"),
"quantity" : 2,
"price" : 200,
"type" : "product",
"isCanceled" : false,
"isDeliverd" : false,
"createdby" : "schooladmin",
"userid" : ObjectId("5b87948d97b752099c086708"),
"isReadyToPickup" : false,
"name" : "The Second Product",
"description" : " "
}
}

How to count the number of values found for a field in MongoDB?

I have to find "exitState" : this is single document , if multiple documents how to find.
{
"_id" : "abc",
"exitType" : "Hang",
"exitState" : "INDIA",
"outcome" : "Successful",
"CEV" : [
{
"LogID" : "CEV",
"ReportingMode" : "N",
"Log_DateTime" : "02:23:2016 00:17:48:913",
"Log_TS" : NumberLong(1456186668913),
"ServiceType" : "TEL",
"MsgID" : "25000",
"SysName" : "test123",
"ProcessID" : "9611",
"Port" : "0",
"ModuleName" : "ArcCDR::CDR_CustomEvent",
"AppName" : "testVXML2",
"MsgTxt" : "abc::24::Test::outcome=Successful$$$exitType=Hang$$$exitState=INDIA",
"Record_Key" : "abc",
"Token1" : "24",
"CustomerName" : "Test",
"CEV_MsgTxt" : "outcome=Successful$$$exitType=Hang$$$exitState=INDIA",
"outcome" : "Successful",
"exitType" : "Hang",
"exitState" : "INDIA"
}
],
"language" : "ENGLISH",
"SC_TS" : ISODate("2016-02-23T00:17:06.060+0000"),
"SC_TimeMS" : NumberLong(1456186626060),
"CDR_SC" : {
"LogID" : "CDR",
"ReportingMode" : "N",
"Log_DateTime" : "02:23:2016 00:17:06:060",
"Log_TS" : NumberLong(1456186626060),
"ServiceType" : "TEL",
"MsgID" : "20010",
"SysName" : "test123",
"ProcessID" : "9611",
"Port" : "0",
"ModuleName" : "TEL_AnswerCall",
"AppName" : "testVXML2",
"MsgTxt" : "abc:SC:testVXML2:452:607856:0223201600170606::",
"Record_Key" : "abc",
"CDR_Type" : "SC",
"Token2" : "testVXML2",
"Token3" : "452",
"Token4" : "607856",
"Token5" : "0223201600170606"
},
" SC_TS_TZ" : ISODate("2016-02-23T00:17:06.060+0000"),
"EC_TS" : ISODate("2016-02-23T00:17:48.910+0000"),
"EC_TS_TZ" : ISODate("2016-02-23T00:17:48.910+0000"),
"EC_TimeMS" : NumberLong(1456186668910),
"CDR_EC" : {
"LogID" : "CDR",
"ReportingMode" : "N",
"Log_DateTime" : "02:23:2016 00:17:48:910",
"Log_TS" : NumberLong(1456186668910),
"ServiceType" : "TEL",
"MsgID" : "20011",
"SysName" : "test123",
"ProcessID" : "9611",
"Port" : "0",
"ModuleName" : "TEL_SRRecognizeV2",
"AppName" : "testVXML2",
"MsgTxt" : "abc:EC:02:0223201600174891::",
"Record_Key" : "abc",
"CDR_Type" : "EC",
"Token2" : "02",
"Token3" : "0223201600174891"
},
"CustomerName" : "Test"
}
Below is my query but unable to find exitState in all documents . Can you please?
dbo.ProductModel.aggregate([
{$match: {"EC_TS":{$gte:new Date(start.toISOString()), $lte:new Date(end.toISOString())}} },
{$group:
{_id: '$exitState', count : {$sum: 1} }
}
]).toArray(function(err, result4) {
console.log(+ result4[0]["exitState"]);
console.log("Total exitState=" + result4[0]["total"]);
q4result=(result4[0]["total"]);
});
});
Maybe you can filter the results:
const result5 = result4.filter((result) => result.exitState && result.exitState !== '');
const nbResults = result5.length;
db.tablename.find({},{"exitStates":1}).count()
https://www.w3resource.com/mongodb-exercises/mongodb-exercise-4.php
I can't understand what is your question exactly. if you want to know how many docs exist in the collection and count them by their exitState, this function retuns what you want. I don't know $match works like this or not, But please log the result for test before doing any action on it.
dbo.ProductModel.aggregate([
{ $match: { "EC_TS": { $gte: new Date( start.toISOString() ),
$lte: new Date( end.toISOString() ) } } },
{ $group: {_id: '$exitState', count : {$sum: 1} } }
], (err, result) => {
if (err) throw err;
console.log(result);
// result is like this:
// [ {"_id": "INDIA", "count": 3}, {"_id": "US", "count": 8} ]
});

How to update an array of object in a document following unique value with mongoose

Giving the following controller:
MyCollection.findByIdAndUpdate(;
ObjectId(""+id+""),
{
$push: {"points":{
$each:[{long:long,
latitude:lat,
reportid:repid,
timestamp:timestamp,
$sort:{reportid:-1}
}}
},
{
safe:true, upsert:true, new:true
},
function(err, model){
console.log(err)
}
)
I initially have my collection like this:
"_id" : ObjectId("58a45fd8ddc4e1251055e197"),
"category" : "Others",
"name" : "edzs",
"points" : [
{
"timestamp" : "2017-03-07T15:57:30",
"repid" : "1609",
"latitude" : 45.644465,
"long" : 5.875074000000012
},
{
"timestamp" : "2017-03-07T14:59:30",
"repid" : "1608",
"latitude" : 45.644465,
"long" : 5.875074000000012
},
{
"timestamp" : "2017-03-07T14:20:30",
"repid" : "1606",
"latitude" : 45.644465,
"long" : 5.875074000000012
}
]
After every call by my controller, I got my collections like this:
"_id" : ObjectId("58a45fd8ddc4e1251055e197"),
"category" : "Others",
"name" : "edzs",
"points" : [
{
"timestamp" : "2017-03-07T16:30:30",
"repid" : "1610",
"latitude" : 45.654465,
"long" : 5.885074000000012
},
{
"timestamp" : "2017-03-07T15:57:30",
"repid" : "1609",
"latitude" : 45.644465,
"long" : 5.875074000000012
},
{
"timestamp" : "2017-03-07T15:57:30",
"repid" : "1609",
"latitude" : 45.644465,
"long" : 5.875074000000012
}
]
My objects inside "points" are cumulated sorted by reportid every call. How can I do to avoid duplicated "reportid" value. is there any commande line in mongoose permitting to controle reportid value in order to have unique in the array?

Resources