Related
[
{
"user_id" : 12453,
"profile_type" : "demo_type_1",
"records" : [
{
"type" : "typ_11",
"value" : {
"high" : 115,
"low" : 78
},
"_meta" : {
"data_type" : "text"
}
},
{
"type" : "type_1",
"files" : [
{
"title" : "path_prescription_1",
"url" : "/file_name.extension"
},
{
"title" : "path_prescription_2",
"url" : "/file_name__1.extension"
}
],
"_meta" : {
"data_type" : "file"
}
}
]
},
{
"user_id" : 12455,
"profile_type" : "demo_type_1",
"records" : [
{
"type" : "typ_11",
"value" : {
"high" : 115,
"low" : 78
},
"_meta" : {
"data_type" : "text"
}
},
{
"type" : "type_1",
"files" : [
{
"title" : "path_prescription_1",
"url" : "/file_name.extension"
},
{
"title" : "path_prescription_2",
"url" : "/file_name__1.extension"
}
],
"_meta" : {
"data_type" : "file"
}
}
]
},
...
]
i want to append prefix the url value to make it an absolute path while retrieving from the database only when the _meta fields data_type is file not for text. The is stored in the above format and retrieved in the same format only with the appended url.
is there any way to do this by using aggregation pipeline ?
You can try using $addFields like this:
db.getCollection('test').aggregate(
[
{
$unwind: {
path:"$records",
preserveNullAndEmptyArrays: true
}
},
{
$unwind: {
path:"$records.files",
preserveNullAndEmptyArrays: true
}
},
{
$addFields: {
"records.files.url":{
$cond: {
if: {
$eq: ['$records.files', undefined]
},
then: null,
else: {$concat: ["some_prefix", "$records.files.url"]}
}
}
}
}
]
)
This will give you:
/* 1 */
{
"_id" : ObjectId("5b6c484b9a8ea6a11c508520"),
"user_id" : 12453.0,
"profile_type" : "demo_type_1",
"records" : {
"type" : "typ_11",
"value" : {
"high" : 115.0,
"low" : 78.0
},
"_meta" : {
"data_type" : "text"
},
"files" : {
"url" : null
}
}
}
/* 2 */
{
"_id" : ObjectId("5b6c484b9a8ea6a11c508520"),
"user_id" : 12453.0,
"profile_type" : "demo_type_1",
"records" : {
"type" : "type_1",
"files" : {
"title" : "path_prescription_1",
"url" : "some_prefix/file_name.extension"
},
"_meta" : {
"data_type" : "file"
}
}
}
/* 3 */
{
"_id" : ObjectId("5b6c484b9a8ea6a11c508520"),
"user_id" : 12453.0,
"profile_type" : "demo_type_1",
"records" : {
"type" : "type_1",
"files" : {
"title" : "path_prescription_2",
"url" : "some_prefix/file_name__1.extension"
},
"_meta" : {
"data_type" : "file"
}
}
}
/* 4 */
{
"_id" : ObjectId("5b6c484b9a8ea6a11c508521"),
"user_id" : 12455.0,
"profile_type" : "demo_type_1",
"records" : {
"type" : "typ_11",
"value" : {
"high" : 115.0,
"low" : 78.0
},
"_meta" : {
"data_type" : "text"
},
"files" : {
"url" : null
}
}
}
/* 5 */
{
"_id" : ObjectId("5b6c484b9a8ea6a11c508521"),
"user_id" : 12455.0,
"profile_type" : "demo_type_1",
"records" : {
"type" : "type_1",
"files" : {
"title" : "path_prescription_1",
"url" : "some_prefix/file_name.extension"
},
"_meta" : {
"data_type" : "file"
}
}
}
/* 6 */
{
"_id" : ObjectId("5b6c484b9a8ea6a11c508521"),
"user_id" : 12455.0,
"profile_type" : "demo_type_1",
"records" : {
"type" : "type_1",
"files" : {
"title" : "path_prescription_2",
"url" : "some_prefix/file_name__1.extension"
},
"_meta" : {
"data_type" : "file"
}
}
}
But remember to ignore records.files.url field when the record is type text.
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", }
]
}
]
}
I am having trouble with the $group stage in my aggregation. I want to group all the "recentPlays.quiz" values together and count the repeated values, so the end result I want from the aggregation is two fields: the quiz object and the total. In this case it would be something like:
{
"recentPlays" : [
{
"quiz" : {
"author" : "red-tester1",
"title" : "Asdffff Dfasdf"
},
"count": 1
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Creation Test 2"
},
"count": 1
},
{
"quiz" : {
"author" : "blue-tester1",
"title" : "Finky Fink"
},
"count": 4
}
]
}
Here is the aggregation I have so far:
db.users.aggregate([
{$match: { "recentPlays.date": {$gte:twentyFourHrsAgo}}},
{$project: {"recentPlays.quiz":1, _id:0}}
]).pretty();
Here is that aggregation's output:
MongoDB shell version: 3.2.1
connecting to: videoQuiz
{
"recentPlays" : [
{
"quiz" : {
"author" : "red-tester1",
"title" : "Asdffff Dfasdf"
}
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Creation Test 2"
}
},
{
"quiz" : {
"author" : "blue-tester1",
"title" : "Finky Fink"
}
},
{
"quiz" : {
"author" : "blue-tester1",
"title" : "Finky Fink"
}
},
{
"quiz" : {
"author" : "blue-tester1",
"title" : "Finky Fink"
}
},
{
"quiz" : {
"author" : "blue-tester1",
"title" : "Finky Fink"
}
}
]
}
Here is the entire collection:
MongoDB shell version: 3.2.1
connecting to: videoQuiz
{
"_id" : ObjectId("580f7be62c6fd3c8065577f5"),
"user" : "blue-tester1",
"email" : "aslfjjcc#lkcjasdc.com",
"createdAt" : ISODate("2016-10-25T15:36:06.933Z"),
"recentPlays" : [
{
"quiz" : {
"author" : "red-tester1",
"title" : "Asdffff Dfasdf"
},
"score" : "0",
"date" : ISODate("2016-10-25T15:36:27.546Z")
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Creation Test 2"
},
"score" : "100",
"date" : ISODate("2016-10-25T15:37:09.142Z")
}
],
"mostRecentQuiz" : {
"author" : "red-tester3",
"title" : "Creation Test 2"
},
"mostRecentQuizTime" : ISODate("2016-10-25T15:37:09.142Z"),
"plays" : 2
}
{
"_id" : ObjectId("580a5dea650296d808082e65"),
"user" : "red-tester3",
"email" : "aldkdk#ccc.com",
"createdAt" : ISODate("2016-10-21T18:26:50.870Z"),
"recentPlays" : [
{
"quiz" : {
"author" : "red-tester2",
"title" : "TOP PLAYED QUIZ - Today"
},
"score" : "0",
"date" : ISODate("2016-10-21T18:27:16.292Z")
},
{
"quiz" : {
"author" : "red-tester2",
"title" : "TOP LIKED QUIZ - TODAY"
},
"score" : "100",
"date" : ISODate("2016-10-21T18:27:32.788Z")
},
{
"quiz" : {
"author" : "red-tester2",
"title" : "TOP LIKED QUIZ - TODAY"
},
"score" : "100",
"date" : ISODate("2016-10-21T18:27:44.497Z")
},
{
"quiz" : {
"author" : "Bertram",
"title" : "frfrf"
},
"score" : "100",
"date" : ISODate("2016-10-21T18:28:43.893Z")
},
{
"quiz" : {
"author" : "Bertram",
"title" : "Here We Go With the New Thing"
},
"score" : "0",
"date" : ISODate("2016-10-21T18:43:51.205Z")
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Presidents of the United States"
},
"score" : "0",
"date" : ISODate("2016-10-23T00:53:29.167Z")
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Presidents of the United States"
},
"score" : "0",
"date" : ISODate("2016-10-23T00:53:44.815Z")
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Creation Test 1"
},
"score" : "100",
"date" : ISODate("2016-10-23T23:50:55.355Z")
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Creation Test 2"
},
"score" : "100",
"date" : ISODate("2016-10-23T23:52:33.210Z")
},
{
"quiz" : {
"author" : "red-tester3",
"title" : "Here Is a New Title"
},
"score" : "100",
"date" : ISODate("2016-10-23T23:58:53.683Z")
}
],
"mostRecentQuiz" : {
"author" : "red-tester3",
"title" : "Here Is a New Title"
},
"mostRecentQuizTime" : ISODate("2016-10-23T23:58:53.683Z"),
"plays" : 10,
"likedQuizzes" : [
{
"title" : "TOP LIKED QUIZ - TODAY",
"author" : "red-tester2",
"date" : ISODate("2016-10-21T18:27:34.893Z")
},
{
"title" : "frfrf",
"author" : "Bertram",
"date" : ISODate("2016-10-21T18:28:45.863Z")
},
{
"title" : "Here We Go With the New Thing",
"author" : "Bertram",
"date" : ISODate("2016-10-21T18:43:53.148Z")
}
],
"createdQuizzes" : [
{
"title" : "Yeah Here We Go",
"id" : ObjectId("580a63f274b9a89c061f973e")
},
{
"title" : "Z Alpha",
"id" : ObjectId("580a641474b9a89c061f973f")
},
{
"title" : "Tags Limit Test",
"id" : ObjectId("580a6bda8d8049ac0bc1df2e")
},
{
"title" : "Tags Limit test2",
"id" : ObjectId("580a6bf98d8049ac0bc1df2f")
},
{
"title" : "Presidents of the United States",
"id" : ObjectId("580c09d28d8049ac0bc1df30")
},
{
"title" : "Creation Test 1",
"id" : ObjectId("580d4cca8d8049ac0bc1df31")
},
{
"title" : "Creation Test 2",
"id" : ObjectId("580d4d2d8d8049ac0bc1df32")
},
{
"title" : "Here Is a New Title",
"id" : ObjectId("580d4ead8d8049ac0bc1df33")
}
]
}
Thanks in advance for any guidance. Please excuse the dummy text in these documents, it is for testing purposes only.
This will be a two step process. The first step is to $unwind the "recentPlays" array. The second step is to $group by "recentPlays.quiz".
For example:
db.users.aggregate([
{ "$match" : { "recentPlays.date": { "$gte" : twentyFourHrsAgo}}},
{ "$project" : {"recentPlays.quiz":1, _id:0}},
{ "$unwind" : "$recentPlays" },
{ "$group" : { "_id" : "$recentPlays.quiz", "total" : { "$sum" : 1 } } }
]).pretty();
I want to find all the values from a subdocument like this:
{ "_id" : ObjectId("XXXXXXXXXXXX"), "consumers" : { "AAAAAAAA" : { "CLIENT" : { "AA" : true } } }, "country" : "ES", "history" : [ ], "last_time_updated" : ISODate("2014-11-28T13:32:19.948Z"), "msisdn" : "123", "operator" : "ES", "time_created" : ISODate("2014-11-28T13:32:19.948Z") }
{ "_id" : ObjectId("XXXXXXXXXXXX"), "consumers" : { "AAAAAAAA" : { "CLIENT" : { "BB" : true } } }, "country" : "ES", "history" : [ ], "last_time_updated" : ISODate("2014-11-28T13:32:19.971Z"), "msisdn" : "123", "operator" : "ES", "time_created" : ISODate("2014-11-28T13:32:19.971Z") }
{ "_id" : ObjectId("XXXXXXXXXXXX"), "consumers" : { "AAAAAAAA" : { "CLIENT" : { "CC" : false } } }, "country" : "ES", "history" : [ ], "last_time_updated" : ISODate("2014-11-28T13:32:19.977Z"), "msisdn" : "123", "operator" : "ES", "time_created" : ISODate("2014-11-28T13:32:19.977Z") }
That include all the values from "CLIENT" that i don't know, i am triying with:
db.collection.find({"consumers" : { "AAAAAAAA" : { "CLIENT" : { $exists : true } } }})
But is not a valid query, please some help?
Thank you very much.
Dot notation can be used to match by fields in a sub document.
db.collection.find({"consumers.AAAAAAAA.CLIENT": {"$exists":true}})
I have a list of documents like this.
[
{
"name" : "test",
"data" : [
{ "code" : "name", "value" : "Diego" },
{ "code" : "nick", "value" : "Darko" },
{ "code" : "special", "value" : true }
]
},
{
"name" : "another",
"data" : [
{ "code" : "name", "value" : "Antonio" },
{ "code" : "nick", "value" : "Tony" }
]
}
]
now I need to find all the documents that:
a) don't contain a "data" item with code "special"
OR
b) contains a "data" item with code "special" and value false
It's like I needed the opposite of $elemMatch or I'm missing something?
I'm assuming that you're inserting each document in your list of documents as a separate member of a collection test.
For a,
db.test.find({ "data.code" : { "$ne" : "special" } })
For b.,
db.test.find({ "data" : { "$elemMatch" : { "code" : "special", "value" : false } } })
Combining the two with $or,
db.test.find({ "$or" : [
{ "data.code" : { "$ne" : "special" } },
{ "data" : { "$elemMatch" : { "code" : "special", "value" : false } } }
] })
Hope this $nin will solve your issues.
I insertd your docs into "so" collection
db.so.find({}).pretty();
{
"_id" : ObjectId("5489cd4f4cb16307b808d4b2"),
"name" : "test",
"data" : [
{ "code" : "name",
"value" : "Diego"
},
{ "code" : "nick",
"value" : "Darko"
},
{ "code" : "special",
"value" : true
}
]
}
{
"_id" : ObjectId("5489cd674cb16307b808d4b3"),
"name" : "another",
"data" : [
{"code" : "name",
"value" : "Antonio"
},
{ "code" : "nick",
"value" : "Tony"
}
]
}
don't contain a "data" item with code "special"
> db.so.find({"data.code":{$nin:["special"]}}).pretty();
{
"_id" : ObjectId("5489cd674cb16307b808d4b3"),
"name" : "another",
"data" : [
{ "code" : "name",
"value" : "Antonio"
},
{ "code" : "nick",
"value" : "Tony"
}
]
}
contains a "data" item with code "special" and value false
db.so.find({$and:[{"data.code":"special"},{"data.value":false}]}).pretty();