MongoDB query with elemMatch for nested array data matching from inside objects [duplicate] - arrays

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 4 years ago.
MongoDB query with elemMatch for nested array data matching from inside objects.
Here we have three project objects and each contains an array of exams with multiple objects.
Here when "project_id" : ObjectId("5b6959e3dc68d21c6613c82d") , The "exams" array contain two times "writer.user_id":ObjectId("5b6959e3dc68d21c6613c77d")
how could i get these two data filtered from the first project object ?
db.exams.insert([{
"project_id" : ObjectId("5b6959e3dc68d21c6613c82d"),
"exams" : [
{
"allotment_type" : "manual",
"exam_id" : 1,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77d"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 1,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 1,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
},
{
"allotment_type" : "manual",
"exam_id" : 2,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77e"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 2,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 2,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
},
{
"allotment_type" : "manual",
"exam_id" : 3,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77d"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 3,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 3,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
}]
},
{
"project_id" : ObjectId("5b6959e3dc68d21c6613c82e"),
"exams" : [
{
"allotment_type" : "manual",
"exam_id" : 1,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77d"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 1,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 1,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
},
{
"allotment_type" : "manual",
"exam_id" : 2,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77e"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 2,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 2,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
},
{
"allotment_type" : "manual",
"exam_id" : 3,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77c"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 3,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 3,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
}]
},
{
"project_id" : ObjectId("5b6959e3dc68d21c6613c82f"),
"exams" : [
{
"allotment_type" : "manual",
"exam_id" : 1,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77d"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 1,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 1,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
},
{
"allotment_type" : "manual",
"exam_id" : 2,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77e"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 2,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 2,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
},
{
"allotment_type" : "manual",
"exam_id" : 3,
"topic" : "something",
"word_count" : 5,
"key_word_density" : 2,
"writer" : {
"user_id" : ObjectId("5b6959e3dc68d21c6613c77c"),
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"editor" : {
"user_id" : 3,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
},
"manager" : {
"user_id" : 3,
"versions" : [
{
"id" : 1,
"file_path" : "abcd"
},
{
"id" : 2,
"file_path" : "abcd"
},
{
"id" : 3,
"file_path" : "abcd"
}
]
}
}]
}]);

You can try with $filter aggregation
db.collection.aggregate([
{ "$project": {
"exams": {
"$filter": {
"input": "$exams",
"as": "exam",
"cond": {
"$eq": [ "$$exam.writer.user_id", ObjectId("5b6959e3dc68d21c6613c77d") ]
}
}
}
}}
])

Related

How to filter from array in a mongo document

I have a collection in mongoDB with documents like:
{
"_id" : ObjectId("some_id"),
"name" : "name",
"field1" : 123,
"field2" : 234,
"arr" : [
{
"a_num" : 3,
"arr" : [
"abc",
"def"
],
},
{
"a_num" : 36,
"arr" : [
"hi"
],
},
{
"a_num" : 34,
"arr" : [
"abc"
],
}
]
}
While I'm using find()
I don't want to get the arr elements where arr has only 1 element, that its value is "abc".
E.g, for the above document, I'd like to get:
{
"_id" : ObjectId("some_id"),
"name" : "name",
"field1" : 123,
"field2" : 234,
"arr" : [
{
"a_num" : 3,
"arr" : [
"abc",
"def"
],
},
{
"a_num" : 36,
"arr" : [
"hi"
],
},
]
}
Any idea how?
Thanks!
You'll need to use the aggregation framework with $filter, like so:
db.collection.aggregate([
{
$addFields: {
arr: {
$filter: {
input: "$arr",
cond: {
$ne: [
"$$this.arr",
[
"abc"
]
]
}
}
}
}
}
])

Checking $gt on a structure element in MongoDB [duplicate]

This question already has answers here:
How to query nested objects?
(3 answers)
Closed 2 years ago.
> db.inventory.find()
{ "_id" : ObjectId("5eb67598bee5213484d45087"), "item" : "journal", "qty" : 25, "status" : "A", "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "tags" : [ "blank", "red" ] }
{ "_id" : ObjectId("5eb67598bee5213484d45088"), "item" : "notebook", "qty" : 50, "status" : "A", "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "tags" : [ "red", "blank" ] }
{ "_id" : ObjectId("5eb67598bee5213484d45089"), "item" : "paper", "qty" : 10, "status" : "D", "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "tags" : [ "red", "blank", "plain" ] }
{ "_id" : ObjectId("5eb67598bee5213484d4508a"), "item" : "planner", "qty" : 0, "status" : "D", "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "tags" : [ "blank", "red" ] }
{ "_id" : ObjectId("5eb67598bee5213484d4508b"), "item" : "postcard", "qty" : 45, "status" : "A", "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "tags" : [ "blue" ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be04608"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be04609"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be0460a"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be0460b"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be0460c"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }
Both of the following queries are resulting in nothing:
> db.inventory.find( { size: { h: { $gt: 14 } } } )
>
> db.inventory.find( { size: { $elemMatch: { h: { $gt: 14 } } } } )
Whereas there is a document greater than 14:
{ "_id" : ObjectId("5eb67598bee5213484d4508a"), "item" : "planner", "qty" : 0, "status" : "D", "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "tags" : [ "blank", "red" ] }
Following syntax doesn't work:
> db.inventory.find( { size.h: { $gt: 14 } } )
2020-05-24T15:08:44.306+0530 E QUERY [js] uncaught exception: SyntaxError: missing : after property id :#(shell):1:25
`
Please explain why.
You need to add dot notation while querying nested documents. Can you try this
db.inventory.find( { 'size.h': { $gt: 14 } } )

Unable to find a match in MongoDB query

> db.inventory.find( )
{ "_id" : ObjectId("5eb67598bee5213484d45087"), "item" : "journal", "qty" : 25, "status" : "A", "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "tags" : [ "blank", "red" ] }
{ "_id" : ObjectId("5eb67598bee5213484d45088"), "item" : "notebook", "qty" : 50, "status" : "A", "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "tags" : [ "red", "blank" ] }
{ "_id" : ObjectId("5eb67598bee5213484d45089"), "item" : "paper", "qty" : 10, "status" : "D", "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "tags" : [ "red", "blank", "plain" ] }
{ "_id" : ObjectId("5eb67598bee5213484d4508a"), "item" : "planner", "qty" : 0, "status" : "D", "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "tags" : [ "blank", "red" ] }
{ "_id" : ObjectId("5eb67598bee5213484d4508b"), "item" : "postcard", "qty" : 45, "status" : "A", "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "tags" : [ "blue" ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be04608"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be04609"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be0460a"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be0460b"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }
{ "_id" : ObjectId("5ebfd02b3a3b38a52be0460c"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }
>
> db.inventory.find( { item: 'journal', qty: '25' } )
>
item: 'journal' with qty '25' is the first item. Why isn't it being shown?
Here is a similar query which is working as per them: https://www.w3resource.com/mongodb-exercises/mongodb-exercise-22.php
db.restaurants.find(
{
"grades.date": ISODate("2014-08-11T00:00:00Z"),
"grades.grade":"A" ,
"grades.score" : 11
},
{"restaurant_id" : 1,"name":1,"grades":1}
);
qty is a number and you're trying to find a string, try:
db.inventory.find( { item: 'journal', qty: 25 } )
(docs)
For most data types, however, comparison operators only perform comparisons on documents where the BSON type of the target field matches the type of the query operand.

Working with Mongodb References inside array next to other content

I want to use the mongodb aggregation framework on 3 Collections that have to "come together" to one Query. The problem is, when I'm referencing to another collection with $lookup it deletes the other content of the array the reference is in.
Heres the collection my aggregation starts in (users):
{
"_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
"kundennummer" : "000001",
"passwort" : "xxx",
"status" : "1",
"onlinestatus" : true,
"kontakt" : {
"email" : "test#test.net"
},
"thing" : [
{
"thing_id" : 2,
"onlinestatus" : false,
"status" : true,
"site" : [
{
"site_id" : 3,
"status": true
},
{
"site_id" : 4,
"status": true
}
],
"refs" : [
{
"thing_id" : 11,
"status" : true
},
{
"thing_id" : 22,
"status" : true
}
]
}
]
}
when I know want site to be extended by the content given in site collection like this:
{
"_id": 11,
"name": "test"
},
{
"_id": 22,
"name": "test2"
}
I tried to use $lookup and the status: true disappeared.
db.users.aggregate([{
$lookup:
{
from: "sites",
localField: "things.site.site_id",
foreignField: "_id",
as: "things.site"
}
}])
edit:
What I want to achieve is the following:
{
"_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
"kundennummer" : "000001",
"passwort" : "xxx",
"status" : "1",
"onlinestatus" : true,
"kontakt" : {
"email" : "test#test.net"
},
"thing" : [
{
"thing_id" : 2,
"onlinestatus" : false,
"status" : true,
"site" : [
{
"site_id" : 11,
"status": true,
"name": "test"
},
{
"site_id" : 12,
"status": true,
"name": "test2"
}
],
"refs" : [
{
"thing_id" : 11,
"status" : true,
"name": "test"
},
{
"thing_id" : 12,
"status" : true,
"name": "test2"
}
]
}
]
}
To use $lookup on the embedded document in MongoDB aggregation you need to use $unwind. It will output a document for each element and then you can use $lookup. You will get results from sites as well with the help of the below query:
db.user.aggregate([
{
$unwind: "$thing"
},
{
$unwind: "$thing.site"
},
{
$unwind: "$thing.refs"
},
{
$lookup: {
from: 'sites',
let: { 'siteId': '$thing.site.site_id' },
pipeline: [
{
$match: {
$expr: {
$eq: ['$_id', '$$siteId']
}
}
},
],
as: 'siteObject'
}
},
{
$lookup: {
from: 'things',
let: { 'thingId': '$thing.refs.thing_id' },
pipeline: [
{
$match: {
$expr: {
$eq: ['$_id', '$$thingId']
}
}
},
],
as: 'thingObject'
}
},
{
$unwind: "$siteObject"
},
{
$unwind: "$thingObject"
},
{
$project: {
"_id" : 1,
"kundennummer" : 1,
"passwort" : 1,
"status" : 1,
"onlinestatus" : 1,
"kontakt" : 1,
"thing": [{
"thing_id" : "$thing.thing_id",
"onlinestatus" : "$thing.onlinestatus",
"status" : "$thing.status",
"site" : {
"site_id":"$thing.site.site_id",
"status":"$thing.site.status",
"siteName":"$siteObject.siteName",
},
"refs" : {
"thing_id":"$thing.refs.thing_id",
"status":"$thing.refs.status",
"siteName":"$thingObject.thingName",
},
}]
}
},
{
$unwind: "$thing"
},
{
$group: {
_id: {
"_id": "$_id",
"kundennummer": "$kundennummer",
"passwort": "$passwort",
"status":"$status",
"onlinestatus":"$onlinestatus",
"kontakt":"$kontakt"
},
thing: { $push: { thing_id: "$thing.thing_id", onlinestatus: "$thing.onlinestatus", status: "$thing.status",site:"$thing.site",refs: "$thing.refs" } }
}
}
])
This will result as below:
{
"_id" : {
"_id" : ObjectId("5c9bea89f4fe8c37175ade58"),
"kundennummer" : "000001",
"passwort" : "xxx",
"status" : "1",
"onlinestatus" : true,
"kontakt" : {
"email" : "test#test.net"
}
},
"thing" : [
{
"thing_id" : 2,
"onlinestatus" : false,
"status" : true,
"site" : {
"site_id" : ObjectId("5caf395e512ab5123bb4b0af"),
"status" : true,
"siteName" : "Moto"
},
"refs" : {
"thing_id" : ObjectId("5cb042ea512ab5123bb4b0b0"),
"status" : true,
"siteName" : "hi"
}
},
{
"thing_id" : 2,
"onlinestatus" : false,
"status" : true,
"site" : {
"site_id" : ObjectId("5caf395e512ab5123bb4b0af"),
"status" : true,
"siteName" : "Moto"
},
"refs" : {
"thing_id" : ObjectId("5cb042ea512ab5123bb4b0b1"),
"status" : true,
"siteName" : "world"
}
},
{
"thing_id" : 2,
"onlinestatus" : false,
"status" : true,
"site" : {
"site_id" : ObjectId("5caf395e512ab5123bb4b0ae"),
"status" : true,
"siteName" : "hello"
},
"refs" : {
"thing_id" : ObjectId("5cb042ea512ab5123bb4b0b0"),
"status" : true,
"siteName" : "hi"
}
},
{
"thing_id" : 2,
"onlinestatus" : false,
"status" : true,
"site" : {
"site_id" : ObjectId("5caf395e512ab5123bb4b0ae"),
"status" : true,
"siteName" : "hello"
},
"refs" : {
"thing_id" : ObjectId("5cb042ea512ab5123bb4b0b1"),
"status" : true,
"siteName" : "world"
}
}
]
}
Result is near by your desired result and i think you should not follow such schema it will make your every query more complex.

mongodb node.js nested array fields concatenation single variable result

I am using using this code inside model aggregation
{$project:{
//for brevity
}},
{$project:{
"employe_detail":{
"$map":{
"input":"$employe_detail",
"as":"names",
"in":{
"name":{"$concat":["$$names.first_name",
" ","$$names.other_names"," ",
"$$names.last_name"]}
}
}
}
}}
This is the result
{ "employe_detail" : [ { "name" : "Brian Smith" } ] }
{ "employe_detail" : [ { "name" : "Josh Clefton" } ] }
{ "employe_detail" : [ { "name" : "Treasure Dwayne" } ] }
when I try to extend the result fields output
{$project:{
//for brevity
}},
{$project:{
"employe_detail":{
"$map":{
"input":"$employe_detail",
"as":"names",
"in":{
"name":{"$concat":["$$names.first_name",
" ","$$names.other_names"," ",
"$$names.last_name"]},
"dept":"$$names.activity_year.activity_detail.dept",
"time_spent": "$$names.activity_year.activity_detail.activity_time_spent.time_spent",
"shift": "$$names.activity_year.activity_detail.activity_time_spent.shift"
}
}
}
}}
The result was
{ "employe_detail" : [ { "name" : "Brian Smith", "dept" : [ [ "spray", "smoothing", "assembling", "packaging" ] ],"time_spent" : [ [ [ 6 ], [ 15 ], [ 7 ], [ 8 ]] ], "shift" : [ [ [ "afternoon" ], [ "afternoon" ], [ "morning" ], [ "morning" ] ] ]} ] }
{ "employe_detail" : [ { "name" : "Josh Clefton", "dept" : [ [ "spray", "shining", "shaping", "smoothing"] ],"time_spent" : [ [ [ 5 ], [ ], [ 8 ], [ 10 ] ] ], "shift" : [ [ [ "afternoon" ], [ ], [ "night" ], [ "night" ] ] ] } ] }
{ "employe_detail" : [ { "name" : "Treasure Dwayne", "dept" : [ [ "spray", "shaping", "smoothing", "assembling" ] ], "time_spent" : [ [ [ 3 ], [ 9 ], [ 13 ], [ 9 ] ] ], "shift" : [ [ [ "morning" ], [ "morning" ], [ "morning" ], [ "morning" ] ] ] } ] }
Please how can I (at least) get something similar to this
{ "employe_detail" : [ { "name" : "Brian Smith",
{"dept" : "spray", "time_spent":6, "shift": "afternoon"},
{"dept" : "smoothing", "time_spent": 15 , "shift": "afternoon"},
{"dept" : "assembling", "time_spent": 7, "shift": "morning"},
{"dept" : "packaging", "time_spent": 8, "shift": "morning"}
}]}
{ "employe_detail" : [ { "name" : "Josh Clefton",
{"dept" : "spray", "time_spent":5, "shift": "afternoon"},
{"dept" : "shining", "time_spent": , "shift": },
{"dept" : "shaping", "time_spent": 8, "shift": "night"},
{"dept" : "smoothing", "time_spent": 10, "shift": "night"}
}]}
Preferably I would like to get a data to become a variable name i.e. for example
instead of time_spent as the variable name, it should be the data for dept that would be the variable name
{ "employe_detail" : [ { "name" : "Josh Clefton",
{"spray":5, "shift": "afternoon"},
{"shining": , "shift": },
{"shaping": 8, "shift": "night"},
{"smoothing": 10, "shift": "night"}
}]}
Please how can i achieve the above
UPDATE
This is sample data
{ "_id" : ObjectId("5bd548380a84d90b5c2bb416"), "details" : {"first_name" : "Brian", "other_names" : "Stone", "last_name" : "Smith", "gender" : "male", "date_of_birth" : ISODate("2009-03-05T00:00:00Z") }, "contact" : [ { "_id" : ObjectId("5bd548380a84d90b5c2bb417"), "residential_address" : "no 5 smith"} ], "health" : [ { "_id" : ObjectId("5bd548380a84d90b5c2bb419"), "illness_name" : "Cold", "sypmtom" : "Sneezing", "normal_treatment" : ""} ], "activity_year" : { "_id" : ObjectId("5bd548380a84d90b5c2bb41a"), "activity_detail" : [ { "_id" : ObjectId("5bd548380a84d90b5c2bb41b"), "dept" : "spray", "activity_time_spent" : [ ] }, { "_id" : ObjectId("5bd548390a84d90b5c2bb41c"), "dept" : "smoothing", "activity_time_spent" : [ ] }, { "_id" : ObjectId("5bd548390a84d90b5c2bb41e"), "dept" : "assembling", "activity_time_spent" : [ ] }, { "_id" : ObjectId("5bd548390a84d90b5c2bb420"), "dept" : "packaging", "activity_time_spent" : [ ] }, { "_id" : ObjectId("5bd54add0a84d90b5c2bb5c5"), "dept" : "shining", "activity_time_spent" : [ ] }, { "_id" : ObjectId("5bff847078c700209c1b515f"), "dept" : "shining", "activity_time_spent" : [ { "_id" : ObjectId("5c1d659083e7551854c1681d"), "time_spent" : 10, "shift" : "afternoon", }, { "_id" : ObjectId("5c1d659083e7551854c1681e"), "time_spent" : 10, "shift" : "afternoon"} ] } ]}, "__v" : 14 },
{ "_id" : ObjectId("5bd548bf0a84d90b5c2bb45b"), "details" : {"first_name" : "Treasure", "other_names" : "Bliss", "last_name" : "Dwayne", "gender" : "female", "date_of_birth" : ISODate("2010-10-28T00:00:00Z") }, "contact" : [ { "_id" : ObjectId("5bd548bf0a84d90b5c2bb45c"), "residential_address" : "no 5 smith"} ], "health" : [ {"_id" : ObjectId("5bd548bf0a84d90b5c2bb45e"), "illness_name" : "Cold", "sypmtom" : "Sneezing", "normal_treatment" : ""} ], "activity_year" : { "_id" : ObjectId("5bd548bf0a84d90b5c2bb45f"), "activity_detail" : [ { "dept" : "spray", "activity_time_spent" : [ ] }, { "dept" : "smoothing", "activity_time_spent" : [ { "_id" : ObjectId("5c200ccea72a3e11f895dc26"), "time_spent" : 3, "shift" : "morning"}, { "_id" : ObjectId("5c215d2eea2ebe1c8043ccde"), "time_spent" : 5, "shift" : "morning"} ] }, { "dept" : "packaging", "activity_time_spent" : [ { "_id" : ObjectId("5c203e75084852185c583e13"), "time_spent" : 9,"shift" : "afternoon"}, { "_id" : ObjectId("5c20f50f4feffe0b00e8e9f7"), "time_spent" : 18,"shift" : "afternoon"} ] }, { "dept" : "shining", "activity_time_spent" : [ { "_id" : ObjectId("5c200b38a72a3e11f895dc08"), "time_spent" : 9, "shift" : "night", }, { "_id" : ObjectId("5c215acdea2ebe1c8043ccc0"), "time_spent" : 9, "shift" : "night" } ] }] }, "__v" : 9 },
None of your expected outputs is a valid JSON document but I hope that below solution will guide you to something that suits your needs.
First of all to create document keys dynamically you have to use $arrayToObject operator which expects an array of two-element arrays as an input. So you can use $addFields operator to reshape your activity_year.activity_detail array into that kind of format. You can use $map to do that and I assume you need first time_spent ($arrayElemAt used to get first element). Then you can use $concatArrays in the next stage to combine that data with name , try:
db.col.aggregate([
{
$addFields: {
activities: {
$map: {
input: "$activity_year.activity_detail",
as: "activity",
in: {
$let: {
vars: {
first_time_spent: { $arrayElemAt: [ "$$activity.activity_time_spent", 0 ] }
},
in: [
[ "$$activity.dept", { $ifNull: [ "$$first_time_spent.time_spent", "" ] } ],
[ "shift", { $ifNull: [ "$$first_time_spent.shift", "" ] } ]
]
}
}
}
}
}
},
{
$project: {
employee_details: {
$concatArrays: [
[{ "name": { $concat: [ "$details.first_name", " ","$details.other_names", " ", "$details.last_name"] } }],
{
$map: {
input: "$activities",
as: "a",
in: { $arrayToObject: "$$a" }
}
}
]
}
}
}
])
Outputs the data in following format:
{
"_id" : ObjectId("5bd548bf0a84d90b5c2bb45b"),
"employee_details" : [
{
"name" : "Treasure Bliss Dwayne"
},
{
"spray" : "",
"shift" : ""
},
{
"smoothing" : 3,
"shift" : "morning"
},
{
"packaging" : 9,
"shift" : "afternoon"
},
{
"shining" : 9,
"shift" : "night"
}
]
}

Resources