Mongo db query for multiple conditions - mongodb

I have a Mongodb Json which look like this
{
"_id" : "5b862ebecebe455a1744",
"userId" : "111",
"courses" : [
{
"stateName" : "statge 1",
"courseId" : "1453",
"courseName" : "Program Training 1",
"duration" : 1,
"lag" : 0,
"courseType" : "1",
"transitionType" : "onComplete",
"scheduledStartDate" : ISODate("2018-07-27T16:23:14.000+05:30"),
"scheduledEndDate" : ISODate("2018-07-27T16:23:14.000+05:30"),
"courseProgress" : 0,
"ASD" : ISODate("2018-09-17T23:18:30.636+05:30"),
"score" : 0
},
{
"stateName" : "stage 2",
"courseId" : "1454",
"courseName" : "Program Assessment 1",
"duration" : 1,
"lag" : 0,
"courseType" : "2",
"transitionType" : "onComplete",
"scheduledStartDate" : ISODate("2018-07-28T16:23:14.000+05:30"),
"scheduledEndDate" : ISODate("2018-07-28T16:23:14.000+05:30"),
"courseProgress" : 0,
"score" : 0
},
{
"stateName" : "stage 3",
"courseId" : "911",
"courseName" : "Program Training 3",
"duration" : 1,
"lag" : 0,
"courseType" : "1",
"transitionType" : "onComplete",
"scheduledStartDate" : ISODate("2018-07-29T16:23:14.000+05:30"),
"scheduledEndDate" : ISODate("2018-07-29T16:23:14.000+05:30"),
"courseProgress" : 0,
"score" : 0
}
],
"userStatus" : 1,
"modified" : ISODate("2018-09-12T11:49:47.400+05:30"),
"created" : ISODate("2018-09-12T11:49:47.400+05:30"),
"completionStatus" : "IP",
"currentState" : {
"courseProgress" : 0,
"stateName" : "statge 1",
"courseId" : "1453",
"courseName" : "Program Training 1"
}
}
I want to find a query where condition is. Please help, as I am new to mongodb
courses.transitionType = oncomplete
(PROGRESS<100||(PROGRESS==100&&ASD exists false))
And print Result something like this which contain these below data
{
"_id" : "5b862ebecebe455a1744",
"courseData" : {
"userId" : "4688",
"courseId" : "1476",
"courseProgress" : 0
}
}

You will have to use an aggregation with a $match stage and a $project to format your result.
The tricky part of your request is that you want an answer by course, but 1 item of your collection contains many courses. So first, you can use the $unwind stage to separate every course
db.[CollectionName].aggregate([
{
$unwind : '$courses'
}
{
$match: {
'courses.transitionType': 'onComplete',
$or: [
{
'courses.courseProgress': { $lt: 100 }
},
{
'courses.courseProgress': 100,
ASD: { $exists: 0 }
}
]
}
},
{
$project: {
_id: '0',
courseData: {
userId: '$courses.userId',
courseId: '$courses.courseId',
courseProgress: '$courses.courseProgress'
}
}

Related

Use match to filter result in lookup? MongoDB

I quite can't get how should I use the pipeline to filter the resulting array of my look up here's the code
{
"_id" : ObjectId("5d73d591b35c943a201837e2"),
"itemName" : "Vape",
"itemSellingPrice" : "350",
"itemPurchasePrice" : "300",
"itemAveragePurchasePrice" : "133.33333333333334",
"itemBaseUnit" : "Unit 2",
"itemReorderPoint" : "100",
"itemTotalQuantity" : "300",
"itemSumQuantity" : "500",
"itemLocation" : "1",
"itemSubLocation" : "sub loc 1",
"itemDateCreated" : ISODate("2019-09-07T16:06:41.521Z"),
"itemID" : 88,
"__v" : 0,
"salesData" : [
{
"_id" : ObjectId("5d73e23ed8422d2ba42049b4"),
"salesOrderCustomerName" : "Manong Puring",
"salesOrderInvoiceNumber" : "1123",
"salesOrderAddress" : "Jan lang",
"salesOrderPaymentStatus" : "Open",
"salesOrderTotalPaid" : "0",
"salesOrderTotalAmount" : "2800",
"salesOrderDiscrepancyAmount" : "2800",
"salesOrderItemList" : [
{
"_id" : ObjectId("5d73e23ed8422d2ba42049b5"),
"salesOrderSelectedItem" : "Vape",
"salesOrderAverage" : "133.33333333333334",
"salesOrderNewPrice" : "350",
"salesOrderPurchasePrice" : "300",
"salesOrderQuantity" : "8",
"salesOrderSubTotal" : "2800"
}
],
"salesOrderDateCreated" : ISODate("2019-09-07T16:00:00.000Z"),
"salesOrderSubLocation" : "sub loc 1",
"salesOrderLocation" : "1",
"salesOrderID" : 62,
"__v" : 0
},
{
"_id" : ObjectId("5d73e37164ade31b40775038"),
"salesOrderCustomerName" : "Manong Puring",
"salesOrderInvoiceNumber" : "123",
"salesOrderAddress" : "Jan lang",
"salesOrderPaymentStatus" : "Open",
"salesOrderTotalPaid" : "0",
"salesOrderTotalAmount" : "350",
"salesOrderDiscrepancyAmount" : "350",
"salesOrderItemList" : [
{
"_id" : ObjectId("5d73e37164ade31b40775039"),
"salesOrderSelectedItem" : "Vape",
"salesOrderAverage" : "133.33333333333334",
"salesOrderNewPrice" : "350",
"salesOrderPurchasePrice" : "300",
"salesOrderQuantity" : "1",
"salesOrderSubTotal" : "350"
}
],
"salesOrderDateCreated" : ISODate("2019-09-07T16:00:00.000Z"),
"salesOrderSubLocation" : "sub loc 2",
"salesOrderLocation" : "1",
"salesOrderID" : 63,
"__v" : 0
}
]
}
I only want to get salesData with salesOrderSubLocation: "sub loc 1"
but it is showing data with sub loc 2 also. Searched for a while but can't find an exact problem with mine.
here's my query
db.getCollection('itemmodels').aggregate(
{ '$match': { itemName: 'Vape' } },
{ '$lookup':
{
from: 'itemmodels',
let: { "itemName": "$itemName" },
pipeline: [
{ $match: {
"salesOrderSubLocation": "sub loc 1",
"salesOrderItemList.salesOrderSelectedItem": "$$itemName"
}
}
],
as: 'salesData'
}
})
any idea guys? I don't want to filter the result in the front end because it my cause some problems with tons of data in the future.

How to sum this this JSON data values below

I am Imran, Please see the JSON data below and tell how to sum the result below:
{
"_id" : "59ae33130d83f7001112ea5e",
"user" : {
"passcode" : "****",
"operator" : "premiereservices",
"phone_num" : "8587366808",
"balance" : 1.99
},
"location_id" : "58ec4e82addba5001160fc07",
"customer_id" : "premiereservices",
"shopping_cart" : {
"item_count" : 2,
"items" : [
{
"customer_id" : "premiereservices",
"barcode" : "666",
"description" : "Test Item",
"price" : 1.99,
"taxable" : false,
"fixed_price_tax" : 0.05,
"__v" : 0
},
{
"customer_id" : "premiereservices",
"barcode" : "777",
"description" : "Test Item",
"price" : 1.99,
"taxable" : false,
"fixed_price_tax" : 0.05,
"__v" : 0
}
],
"total_due" : 4.08
},
"cart_total" : 4.08,
"Date" : "2017-09-04T23:16:03-06:00",
"__v" : 0
}
{
"_id" : "59ae38f186c7e70011a4e224",
"location_id" : "58ec522a99da86001123ec47",
"customer_id" : "premiereservices",
"user" : {
"phone_num" : "4129514766",
"balance" : 0.03
},
"cart_total" : 3.55,
"shopping_cart" : {
"items" : [
{
"barcode" : "028400020008",
"description" : "Smartfood White Cheddar Popcorn",
"price" : 1.25,
"taxable" : false,
"tax_collected" : 0
},
{
"barcode" : "012000286209",
"description" : "Pureleaf Unsweetened Tea",
"price" : 2.3,
"taxable" : false,
"tax_collected" : 0
}
]
},
"Date" : "2017-09-04T23:41:05-06:00",
"__v" : 0
}
{
"_id" : "59ae3c569ce8ec00112775d6",
"location_id" : "58ec522a99da86001123ec47",
"customer_id" : "premiereservices",
"user" : {
"phone_num" : "7192358363",
"balance" : 9.99
},
"cart_total" : 3.25,
"shopping_cart" : {
"items" : [
{
"barcode" : "10002",
"description" : "GnG Burrito Bacon/GChili/Potato",
"price" : 3.25,
"taxable" : true,
"tax_collected" : 0
}
]
},
"Date" : "2017-09-04T23:55:34-06:00",
"__v" : 0
}
Result Will be
cart_total: 10.88
price: 10.78
tax_collected: 0
Please anybody help me what will be the aggregate query functions
There you go:
db.collection.aggregate({
$project: { // for each document...
cart_total: 1, // ...keep the "cart_total" field
price: { $sum: "$shopping_cart.items.price" }, // ...sum up all "price" fields
tax_collected: { $sum: "$shopping_cart.items.tax_collected" } // ...sum up all "price" fields
}
}, {
$group: {
_id: null, // group all documents into the same bucket and sum up a bunch of values
cart_total: { $sum: "$cart_total" },
price: { $sum: "$price" },
tax_collected: { $sum: "$tax_collected" }
}
}, {
$project: {
_id: 0 // remove the "_id" field
}
})

Query to group distinct values and show sum of array values in mongodb

I wanted to group by cart.name and find the sum of cart.qty in mongodb. Below is sample document
{
"_id" : ObjectId("581323379ae5e607645cb485"),
"cust" : {
"name" : "Customer 1",
"dob" : "09/04/1989",
"mob" : 999999999,
"loc" : "Karimangalam",
"aadhar" : {
}
},
"cart" : [
{
"name" : "Casual Shirt",
"qty" : 1,
"mrp" : 585,
"discperc" : 10,
"fit" : null,
"size" : "L"
},
{
"name" : "Casual Shirt",
"qty" : 1,
"mrp" : 500,
"discperc" : 0,
"fit" : null,
"size" : "L"
},
{
"name" : "Cotton Pant",
"qty" : 1,
"mrp" : 850,
"discperc" : 0,
"fit" : null,
"size" : "34"
},
{
"name" : "Cotton Pant",
"qty" : 1,
"mrp" : 1051,
"discperc" : 10,
"fit" : null,
"size" : "34"
}
],
"summary" : {
"bill" : 2822.4,
"qty" : 4,
"mrp" : 2986,
"received" : "2800",
"balance" : -22.40000000000009
},
"createdAt" : ISODate("2016-10-28T10:06:47.367Z"),
"updatedAt" : ISODate("2016-10-28T10:06:47.367Z")
}
There are many document like this. I want the output as below distinct product name (cart.name) and its total qty
{Casual Shirt , 30},
{Cotton Pant , 10},
{T-Shirt , 15},
{Lower , 12}
Here is my query trying to group by cart.name and sum qty
db.order.aggregate( [
{ $unwind: "$cart" },
{ $group: {
_id: "$cart.name",
totalQTY: { $sum:"$cart.qty"},
count: { $sum: 1 }
}
}
] )
but it displays wrong totalQty values for each product name. I checked manually.
Please give me the correct query.
> db.collection.aggregate([
... { $unwind: "$cart" },
... { $group: { "_id": "$cart.name", totalQTY: { $sum: "$cart.qty" }, count: { $sum: 1 } } }
... ])
I get the following result:
{ "_id" : "Cotton Pant", "totalQTY" : 2, "count" : 2 }
{ "_id" : "Casual Shirt", "totalQTY" : 11, "count" : 2 }
I'm not sure what you're looking for, it looks like your aggregation pipeline is correct. (Note I changed the Casual Shirt Quantity to be 10 and 1 respectively)

Aggregate inside document in mongodb

I have document sales
db.sale.findOne({_id : ObjectId("52ea4dd29dbc7923107ddb97")})
{
"_id" : ObjectId("52ea4dd29dbc7923107ddb97"),
"firm" : ObjectId("52e56c009dbc794999ea5c3d"),
"patient" : {
"last" : "",
"first" : ""
},
"doc" : "",
"hospital" : "",
"discount" : 0,
"dd" : "",
"mode" : "cash",
"invoice" : "300114-undefined-1",
"items" : [
{
"bat" : "BJFE",
"narco" : 0,
"name" : "GDRNCCD",
"mrp" : 1,
"free" : 0,
"qty" : 1,
"item_discount" : 0,
"wpr" : 1,
"exp" : "1425168000000"
},
{
"bat" : "",
"narco" : 0,
"name" : "GDRN vbhjdsfb",
"mrp" : 1,
"free" : 0,
"qty" : 1,
"item_discount" : 0,
"wpr" : 0,
"exp" : "[object Object]"
},
{
"bat" : "",
"narco" : 0,
"name" : "GDRN vbhjdsfb",
"mrp" : 1,
"free" : 0,
"qty" : 1,
"item_discount" : 0,
"wpr" : 0,
"exp" : "[object Object]"
}
],
"date" : ISODate("2014-01-30T00:00:00Z"),
"mob" : "",
"email" : ""
}
How can I Aggregate total numbers if items in one field and sum up mrp *qty of all the items into one field.
I have read the mognodb aggregation but it only aggregates among group of matched documents not inside a single document. Is it possile?
{
"_id" : ObjectId("52ea4dd29dbc7923107ddb97"),
"firm" : ObjectId("52e56c009dbc794999ea5c3d"),
'total_items' : items.length,
"total" : mrp*qty of all items,
}
db.sales.aggregate(
{$unwind: "$items"},
{$project: {_id: 1,firm:1, total: {$multiply: ["$items.mrp", "$items.qty"]}}},
{$group: {_id: {"id":"$_id", firm:"$firm"}, count: {$sum:1} , total : {$sum:"$total"}}}
)
With a slight change : _id contains id and firm, you will need an extra projection to match your desired document, but I don't think it's important.
Plus, you can easily change to group by farm only
Thanks to Orid,I tried this,
db.sale.aggregate(
{ $match :{ firm :ObjectId("52e56c009dbc794999ea5c3d") } },
{$project : {day : {$dayOfMonth : '$date'},items :1,patient :1,invoice :1}},
{$match : {day: {$gte : new Date().getDate()}}},
{$unwind : "$items"},
{$project: {_id: 1,patient:1,invoice :1, total: {$multiply: ["$items.mrp", "$items.qty"]}}},
{$group: {_id: {"id":"$_id", invoice:"$invoice",patient :"$patient"}, count: {$sum:1} , total : {$sum:"$total"}}})
Result
{
"result" : [
{
"_id" : {
"id" : ObjectId("52eab6129dbc7923107ddbaf"),
"invoice" : "310114-undefined-1",
"patient" : {
"last" : "",
"first" : ""
}
},
"count" : 2,
"total" : 25
},
{
"_id" : {
"id" : ObjectId("52eab6129dbc7923107ddbb0"),
"invoice" : "310114-undefined-1",
"patient" : {
"last" : "",
"first" : ""
}
},
"count" : 1,
"total" : 1
},
{
"_id" : {
"id" : ObjectId("52eab6129dbc7923107ddbae"),
"invoice" : "310114-undefined-1",
"patient" : {
"last" : "",
"first" : ""
}
},
"count" : 2,
"total" : 5
}
],
"ok" : 1
}

MongoDB groupby query

I have colletions containing records like
{ "type" : "me", "tid" : "1" }
{ "type" : "me", "tid" : "1" }
{ "type" : "me", "tid" : "1" }
{ "type" : "you", "tid" : "1" }
{ "type" : "you", "tid" : "1" }
{ "type" : "me", "tid" : "2" }
{ "type" : "me", "tid" : "2"}
{ "type" : "you", "tid" : "2"}
{ "type" : "you", "tid" : "2" }
{ "type" : "you", "tid" : "2"}
I have want result like below
[
{"tid" : "1","me" : 3,"you": 2},
{"tid" : "2","me" : 2,"you": 3}
]
I have tried group and; aggregate queries doesn't get required result format.
below is the group query.
db.coll.group({
key: {tid : 1,type:1},
cond: { tid : { "$in" : [ "1","2"]} },
reduce: function (curr,result) {
result.total = result.total + 1
},
initial: { total : 0}
})
it result is like
[
{"tid" : "1", "type" : "me" ,"total": 3 },
{"tid" : "1","type" : "you" ,"total": 2 },
{"tid" : "2", "type" : "me" ,"total": 2 },
{"tid" : "2","type" : "you" ,"total": 3 }
]
following is aggregate query
db.coll.aggregate([
{$match : { "tid" : {"$in" : ["1","2"]}}},
{$group : { _id : {tid : "$tid",type : "$type"},total : {"$sum" : 1}}}
])
gives following result
{
"result" :
[
{"_id" : {"tid" : "1","type" : "me"},"total" : 3},
{"_id" : {"tid" : "2","type" : "me" },"total" : 2},
{"_id" : {"tid" : "2","type" : "you"},"total" : 3}
]
"ok" : 1
}
it is possible to obtain I specified result or I have to do some manipulation in my code.
Thanks
If you change your aggregation to this:
db.so.aggregate([
{ $match : { "tid" : { "$in" : ["1", "2"] } } },
{ $group : {
_id : { tid : "$tid", type : "$type" },
total : { "$sum" : 1 }
} },
{ $group : {
_id : "$_id.tid",
values: { $push: { type: "$_id.type", total: '$total' } }
} }
])
Then your output is:
{
"result" : [
{
"_id" : "1",
"values" : [
{ "type" : "you", "total" : 2 },
{ "type" : "me", "total" : 3 }
]
},
{
"_id" : "2",
"values" : [
{ "type" : "me", "total" : 2 },
{ "type" : "you", "total" : 3 }
]
}
],
"ok" : 1
}
Although that is not the same as what you want, it is going to be the closest that you can get. And in your application, you can easily pull out the values in the same was as with what you would like to get out of it.
Just keep in mind, that in general you can not promote a value (you, me) to a key — unless your key is of a limited set (3-4 items max).