Mongodb If then else, unwinding - mongodb

I have documnet structure like below.
{
"_id" : ObjectId("5852c49ba35fe"),
"date" : "20100101",
"p9" : "PWR_FSA",
"p10" : "00278",
"p11" : "002",
"gs" : [
{
"tis" : [
{
"rr" : "00",
"ul" : [
{
"amnt" : 1.0,
"su" : "N"
}
]
}
],
"type" : "PQR"
}
],
"trig_id" : "255"
}
{
"_id" : ObjectId("59fdc49ba35fe"),
"date" : "20100101",
"p9" : "PWR_FSA",
"p10" : "00278",
"p11" : "002",
"gs" : [
{
"mis" : [
{
"rr" : "00",
"tl" : [
{
"amnt" : -1.5,
"su" : "N"
}
]
}
],
"type" : "ABC"
}
],
"trig_id" : "255"
}
Now i want to aggregare the amount on the basis of p9 so i have written below query.
I am gettiing an error at then : {{$unwind : "$gs.tis"},{$unwind : "$gs.tis.ul"}},
Where i am going wrong? Also Can i do unwinding in Then clause ?
db.TB.aggregate({$match :{$and :[{"trig_id" : "255"}]}},
{ $unwind : "$gs" },
{$project: {_id :1,
"amnt" :{
$concat : [ {
$cond : { if : {"gs.type" : {$eq : "PQR"}} ,
then : {{$unwind : "$gs.tis"},{$unwind : "$gs.tis.ul"}},
$cond : { if : {$match : {"gs.tis.ul.su": "N"}} , then : {$gs.tis.ul.amnt} , else: {""}}
else : "" }
}]}},
"total" : { $sum : 1 }
}},
{$group :{"_id": "$p9",
"amnt": {"$sum": "$amnt"}
}
})

Related

Mongodb update nested array by id

I have the following document and want to update state
Document ID: ObjectId("5a4e5a448b70d50e34d204a5")
Target ID: ObjectId("5a4e5a438b70d50e34d203ea")
I have no idea how to update the state to e.g. 4
{
"_id" : ObjectId("5a4e5a448b70d50e34d204a5"),
"name" : "Wirtschaftsdienst",
"date" : ISODate("2012-10-07T00:00:00.000Z"),
"comment" : null,
"tasks" : [
{
"name" : "Speisen und Getränke",
"sections" : [
{
"start" : 46800,
"end" : 72000,
"entirely" : true,
"assistants" : [
{
"assistant" : {
"_id" : ObjectId("5a4e5a438b70d50e34d203ea")
},
"state" : 3
},
{
"assistant" : {
"_id" : ObjectId("5a4e5a438b70d50e34d203f4")
},
"state" : 3
}
]
}
]
}
]
}
Use positional operator $[] along with arrayFilters to get your job done!
Try this query:
db.collection.update(
{"_id" : ObjectId("5a4e5a448b70d50e34d204a5")},
{$set: {"tasks.$[].sections.$[].assistants.$[element].state":4}},
{arrayFilters: [ {"element.assistant":{"_id" :
ObjectId("5a4e5a438b70d50e34d203ea")} }
], multi:true}
)
And the output is:
/* 1 */
{
"_id" : ObjectId("5a4e5a448b70d50e34d204a5"),
"name" : "Wirtschaftsdienst",
"date" : ISODate("2012-10-07T00:00:00.000Z"),
"comment" : null,
"tasks" : [
{
"name" : "Speisen und Getränke",
"sections" : [
{
"start" : 46800,
"end" : 72000,
"entirely" : true,
"assistants" : [
{
"assistant" : {
"_id" : ObjectId("5a4e5a438b70d50e34d203ea")
},
"state" : 4.0
},
{
"assistant" : {
"_id" : ObjectId("5a4e5a438b70d50e34d203f4")
},
"state" : 3.0
}
]
}
]
}
]
}

How to join deeply nested array?

Here is my actual database schema.
company_id is reference object of companies collection and booking_days.consultants.consultant_id is reference object of users collection.
I want to join embedded document with company_id and booking_days.consultants.consultant_id.
{
"_id" : ObjectId("5a7040d664544e1bb877deae"),
"company_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"booking_days" : [
{
"booking_date" : ISODate("2018-01-31T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877deca"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877decc")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877decb")
}
]
},
{
"booking_date" : ISODate("2018-02-01T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec6"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877dec9")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877dec8")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877dec7")
}
]
},
{
"booking_date" : ISODate("2018-02-02T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec4"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877dec5")
}
]
},
],
"__v" : 0
}
I am using below query.
db.getCollection('booking_days').aggregate(
[
{ $match: { company_id:ObjectId("5a6eb43f437e6a0d9e00c92f") } },
{
$lookup: {
localField: "company_id",
from: "companies",
foreignField: "_id",
as: "companies"
},
},
{
$lookup: {
localField: "booking_days.consultants.consultant_id",
from: "users",
foreignField: "_id",
as: "userssss"
},
},
{
$unwind:"$companies"
},
]
)
Actual Output
{
"_id" : ObjectId("5a7040d664544e1bb877deae"),
"company_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"booking_days" : [
{
"booking_date" : ISODate("2018-01-31T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877deca"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877decc")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877decb")
}
]
},
{
"booking_date" : ISODate("2018-02-01T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec6"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877dec9")
},
]
},
],
"__v" : 0,
"companies" : {
"_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"first_name" : "Adrienne Runolfsson",
},
"users" : [
{
"_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"first_name" : "Christ Hamill",
},
{
"_id" : ObjectId("5a6f2854ce7d6938de1dd52e"),
"first_name" : "Miss Dina Kovacek",
},
]
}
Excepted output. consultant data will come in booking_days.consultants array.
{
"_id" : ObjectId("5a7040d664544e1bb877deae"),
"company_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"booking_days" : [
{
"booking_date" : ISODate("2018-01-31T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877deca"),
"consultants" : [
{
"consultant_id" : {
"_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"first_name" : "Christ Hamill",
},
"_id" : ObjectId("5a7040d664544e1bb877decc")
},
{
"consultant_id" : {
"_id" : ObjectId("5a6f2854ce7d6938de1dd52e"),
"first_name" : "Miss Dina Kovacek",
},
"_id" : ObjectId("5a7040d664544e1bb877decb")
}
]
},
{
"booking_date" : ISODate("2018-02-01T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec6"),
"consultants" : [
{
"consultant_id" : {
"_id" : ObjectId("5a6f2854ce7d6938de1dd52e"),
"first_name" : "Miss Dina Kovacek",
},
"_id" : ObjectId("5a7040d664544e1bb877dec9")
},
]
},
],
"__v" : 0,
"companies" : {
"_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"first_name" : "Adrienne Runolfsson",
},
}
As such you have to $unwind the localField when it is an embedded document array expect in some cases where localField is an array of scalar ids.
$unwind twice as consultant array is two levels deep followed by $lookup to get the name and $group to get back the expected output.
db.getCollection('booking_days').aggregate([
{"$match":{"company_id":ObjectId("5a6eb43f437e6a0d9e00c92f")}},
{"$lookup":{"localField":"company_id","from":"companies","foreignField":"_id","as":"companies"}},
{"$unwind":"$companies"},
{"$unwind":"$booking_days"},
{"$unwind":"$consultants"},
{"$lookup":{
"localField":"booking_days.consultants.consultant_id",
"from":"users",
"foreignField":"_id",
"as":"booking_days.consultants.consultant_id"
}},
{"$group":{
"_id":{"_id":"$_id","booking_days_id":"$booking_days._id"},
"company_id":{"$first":"$company_id"},
"booking_date":{"$first":"$booking_days.booking_date"},
"companies":{"$first":"$companies"},
"consultants":{"$push":"$booking_days.consultants"}
}},
{"$group":{
"_id":"$_id._id",
"company_id":{"$first":"$company_id"},
"companies":{"$first":"$companies"},
"booking_days":{
"$push":{
"_id":"$_id.booking_days_id",
"booking_date":"$booking_date",
"consultants":"$consultants"
}
}
}}
])
{"Id": "5b87a4c79a9c3feac943fc6c",
"comments" : [
{
"likes" : [],
"_id" : ObjectId("5b87a4c79a9c3feac943fc6c"),
"comment" : "string",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"commentId" : "7d2a05d1-2026-4a13-a5c1-318ed80d1b38",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
}
]
},
{
"likes" : [],
"_id" : ObjectId("5b87c301c8a07efa2599c29e"),
"comment" : "testing",
"accountId" : "cfd29f53-d73e-480c-9cfa-ea42b4119266",
"commentId" : "0676047b-1712-4f70-89d5-29c1abe03eaf",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
}
]
}
]
}
accountId is in differnt connection
// Expected Out Put
{"Id": "5b87a4c79a9c3feac943fc6c",
"comments" : [
{
"likes" : [],
"_id" : ObjectId("5b87a4c79a9c3feac943fc6c"),
"comment" : "string",
"name" : "apple",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"name" : "apple",
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"name" : "apple",
}
]
},
{
"likes" : [],
"_id" : ObjectId("5b87c301c8a07efa2599c29e"),
"comment" : "testing",
"name" : "ball",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"name" : "apple",
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"name" : "apple", }
]
}
]
}

Delete portion of Sub Document Collection in Mongodb

I am trying to delete a section of sub documents from a collections..
Tried (and many others):
db.collection.remove( {'Segments': {$gte: '20150612141038' }} )
db.collection.remove( { 'Segments.$' : {$gte: '0150612141038' }} )
db.collection.deleteMany( { 'Segments.$' : {$gte: '0150612141038' }} )
db.collection.deleteOne( { 'Segments.$' : {$eq: '0150612141038' }} )
just can't figure out what I am doing wrong...
{
"_id" : ObjectId("56e32c5147e030bc0a000035"),
"Date" : "2015-06-12",
"UnitID" : "5",
"Segments" : {
"20150612141037" : {
"Parameters" : {
"647" : "0",
"649" : "16",
"653" : "0",
"655" : "0",
"656" : "0",
"658" : "98",
"664" : "447.0486",
"666" : "442.7083",
"677" : "122.8004",
}
},
"20150612141038" : {
"Parameters" : {
"658" : "96",
"664" : "451.3889",
"666" : "447.0486",
"677" : "122.7892"
}
},
"20150612141039" : {
"Parameters" : {
"658" : "44",
"664" : "442.7083",
"677" : "122.8004",
"704" : "1"
}
},
First of all I think your queries are wrong.
If you try this query to the mongoShell:
db.bios.find({'Segments': {$gte: '20150612141038'}})
you don't have anything as output because 20150612141038 is a document and not a field. Maybe you can reshape your schema to set 20150612141038 as a field and Segments as an array of documents:
{
"_id" : ObjectId("56e32c5147e030bc0a000035"),
"Date" : "2015-06-12",
"UnitID" : "5",
"Segments" : [
{
"segmentId" : "20150612141037",
"Parameters" : {
"647" : "0",
"649" : "16",
"653" : "0",
"655" : "0",
"656" : "0",
"658" : "98",
"664" : "447.0486",
"666" : "442.7083",
"677" : "122.8004"
}
},
{
"segmentId" : "20150612141038",
"Parameters" : {
"658" : "96",
"664" : "451.3889",
"666" : "447.0486",
"677" : "122.7892"
}
},
{
"segmentId" : "20150612141039",
"Parameters" : {
"658" : "44",
"664" : "442.7083",
"677" : "122.8004",
"704" : "1"
}
}
]
}
and then you can use $pull operator to remove documents from Segments array where the field Segments.segmentId has a certain value:
db.collection.update({},
{$pull:{Segments:{"segmentId":{$eq:"20150612141039"}}}},
{ multi: true}
)

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).

Do $sort works for sub array document

I have a collection which has a field of array kind. I want to sort on the basis of a field of sub-array but Mongo is not sorting the data.
My collection is:
{
"_id" : ObjectId("51f1fcc08188d3117c6da351"),
"cust_id" : "abc123",
"ord_date" : ISODate("2012-10-03T18:30:00Z"),
"status" : "A",
"price" : 25,
"items" : [{
"sku" : "ggg",
"qty" : 7,
"price" : 2.5
}, {
"sku" : "ppp",
"qty" : 5,
"price" : 2.5
}]
}
My Query is:
db.orders.aggregate([
{ "$unwind" : "$items"} ,
{ "$match" : { }} ,
{ "$group" : { "items" : { "$addToSet" : { "sku" : "$items.sku"}} , "_id" : { }}} ,
{ "$sort" : { "items.sku" : 1}} ,
{ "$project" : { "_id" : 0 , "items" : 1}}
])
Result is:
"result" : [
{
"items" : [
{
"sku" : "ppp"
},
{
"sku" : "ggg"
}
]
}
],
"ok" : 1
}
Whereas "sku":"ggg" should come first when it is ascending.
You weant to do the sort BEFORE you regroup:
db.orders.aggregate([
{ "$unwind" : "$items"} ,
{ "$sort" : { "items.sku" : 1}},
{ "$match" : { }} ,
{ "$group" : { "items" : { "$push" : { "sku" : "$items.sku"}} , "_id" : null}} ,
{ "$project" : { "_id" : 0 , "items" : 1}}
])