Mongo Filter Query Nested with mulitple and - mongodb

Following is my query does exactly match with my document but still not getting output.Don't know why. Following is the document as well.
db.getCollection("analytics").find(
{
"$and" : [
{
"archive" : false
},
{
"platform" : "WEB"
},
{
"vendorId" : "3c7adbfe-14d7-4b26-9134-7e05d56573cc"
},
{
"createdAt" : {
"$gte" : 1578268800000.0
}
},
{
"createdAt" : {
"$lte" : 1580860800000.0
}
},
{
"$and" : [
{
"data.mobile" : "123"
},
{
"page" : "Loan Application"
},
{
"event" : "click"
}
]
},
{
"$and" : [
{
"data.aadharNumber" : "123"
},
{
"page" : "Personal Information"
},
{
"event" : "click"
}
]
},
{
"$and" : [
{
"data.totalExp" : "5"
},
{
"page" : "Professional Information"
},
{
"event" : "click"
}
]
}
]
}
);
Documents :
[
{
"page": "Loan Application",
"event": "click",
"loggedIn": true,
"vendorId": "3c7adbfe-14d7-4b26-9134-7e05d56573cc",
"data": {
"first": "Praveen",
"mobile": "1234"
},
"platform": "WEB"
},
{
"page": "Personal Information",
"event": "click",
"loggedIn": true,
"vendorId": "3c7adbfe-14d7-4b26-9134-7e05d56573cc",
"data": {
"panNumber": "123",
"aadharNumber": "123"
},
"platform": "WEB"
},
{
"page": "Professional Information",
"event": "click",
"loggedIn": true,
"vendorId": "3c7adbfe-14d7-4b26-9134-7e05d56573cc",
"data": {
"totalExp": "5"
},
"platform": "WEB"
}
]

There are a lot of issues going on with your query, you can try below query to return all documents :
db.getCollection("analytics").find({
$expr: {
$and: [
{
$eq: [
"$platform",
"WEB"
]
},
{
$eq: [
"$vendorId",
"3c7adbfe-14d7-4b26-9134-7e05d56573cc"
]
},
{
$or: [
{
"$and": [
{
"data": {
"mobile": "123"
}
},
{
"page": "Loan Application"
},
{
"event": "click"
}
]
},
{
"$and": [
{
"data": {
"aadharNumber": "123"
}
},
{
"page": "Personal Information"
},
{
"event": "click"
}
]
},
{
"$and": [
{
"data": {
"totalExp": "5"
}
},
{
"page": "Professional Information"
},
{
"event": "click"
}
]
}
]
}
]
}
})
Test : MongoDB-Playground

Related

Matching a value in subdocument array and matching array to _id

I have a collection of Users which looks like this:
{
"_id": {
"$oid": "5ff6298f2056ad02272d10f2"
},
"name": "Billy Bob",
"story": {
"posts": [
{"id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"},
{"id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"},
{"id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"}
],
"whoCanView": [{
"$oid": "5ff891bd749ed24316272317"
}, {
"$oid": "5ffc89392056ad02272d10f3"
}]
}
}
I want to get all users and their stories listed in an array which I call "contacts". The user currently querying the collection may only get results if their userId is in the "whoCanView" array.
This is what i have so far but doesn't seem to be working:
users.find({'story' : {
'$elementMatch' : {
'_id' : {'$in' : contacts},
ObjectID(userId) : {'$in' : 'story.whoCanView'}
}
}
});
Any guidance would be appreciated. Thanks!
ObjectID(userId) : {'$in' : 'story.whoCanView'}
Above line along with the usage of $elemMatch operator is wrong in your code. Try this query instead:
let contacts = [
ObjectId("5ff6298f2056ad02272d10f2"),
ObjectId("5ff6298f2056ad02272d10f3"),
ObjectId("5ff6298f2056ad02272d10f4")
];
let userId = ObjectId("5ff891bd749ed24316272317");
db.users.find(
{
"_id": { $in: contacts },
"story.whoCanView": userId
},
{
"strories": "$story.posts"
}
);
Output when userId is ObjectId("5ff891bd749ed24316272317"):
/* 1 createdAt:1/7/2021, 2:50:15 AM*/
{
"_id" : ObjectId("5ff6298f2056ad02272d10f2"),
"strories" : [
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
},
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
},
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
}
]
},
/* 2 createdAt:1/7/2021, 2:50:15 AM*/
{
"_id" : ObjectId("5ff6298f2056ad02272d10f3"),
"strories" : [
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
},
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
},
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
}
]
},
/* 3 createdAt:1/7/2021, 2:50:15 AM*/
{
"_id" : ObjectId("5ff6298f2056ad02272d10f4"),
"strories" : [
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
},
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
},
{
"id" : "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45"
}
]
}
Output when userId is ObjectId("5ff891bd749ed24316272318"):
[]
Test data in users collection:
[
{
"_id": ObjectId("5ff6298f2056ad02272d10f2"),
"name": "Billy Bob",
"story": {
"posts": [
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" }
],
"whoCanView": [
ObjectId("5ff891bd749ed24316272317"),
ObjectId("5ffc89392056ad02272d10f3")
]
}
},
{
"_id": ObjectId("5ff6298f2056ad02272d10f3"),
"name": "Billy Bob",
"story": {
"posts": [
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" }
],
"whoCanView": [
ObjectId("5ff891bd749ed24316272317"),
ObjectId("5ffc89392056ad02272d10f3")
]
}
},
{
"_id": ObjectId("5ff6298f2056ad02272d10f4"),
"name": "Billy Bob",
"story": {
"posts": [
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" }
],
"whoCanView": [
ObjectId("5ff891bd749ed24316272317"),
ObjectId("5ffc89392056ad02272d10f3")
]
}
},
{
"_id": ObjectId("5ff6298f2056ad02272d10f5"),
"name": "Billy Bob",
"story": {
"posts": [
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" },
{ "id": "b4a12557-4dfa-47eb-9f27-7bbcad0f4c45" }
],
"whoCanView": [
ObjectId("5ff891bd749ed24316272317"),
ObjectId("5ffc89392056ad02272d10f3")
]
}
}
]

mongo convert single object to one element array

I have the following problem. In this example dataset:
https://mongoplayground.net/p/itNnrDzZ4JQ
[
{
"name": "test",
"questions": [
{
"headline": "headline 1",
"answer": {
"#id": "001",
"m_IMG": {
"type": "06",
"img": {
"#id": "1111",
"shape": [
{
"#src": "/1_1.jpg",
"#type": "Z05"
},
{
"#src": "/1_2.jpg",
"#type": "Z08"
}
]
}
},
"text": "text1"
}
},
{
"headline": "Headline 2",
"answer": [
{
"#id": "001",
"m_IMG": {
"#type": "24",
"img": {
"#id": "1111",
"shape": {
"#src": "/2_1.jpg",
"#type": "Z05"
}
},
"text": "Test2"
}
},
{
"#id": "002",
"m_IMG": {
"#typeName": "",
"#type": "25",
"img": {
"#id": "2222",
"shape": [
{
"#src": "/2_1.jpg",
"#type": "Z05"
},
{
"#src": "2_2.jpg",
"#type": "Z08"
}
]
}
},
"text": "Test3"
}
]
}
]
}
]
You will find that if only a single answer to a question exists it is represented as an object. If more than one exists then it is an array. This is also true in the shape node. I wonder what is the best way to convert those nodes to be always arrays (so if one answer exists it would be an array of one element).
$map to iterate loop of questions array
check condition if answer is not array then put into array bracket and input as $map to iterate loop of answer array
check condition is not shape array ten wrap it in to array bracket
$mergeObjects with sub documents img, m_IMG objects
$mergeObjects with current document and updated answer array
db.collection.aggregate([
{
$set: {
questions: {
$map: {
input: "$questions",
as: "q",
in: {
$mergeObjects: [
"$$q",
{
answer: {
$map: {
input: {
$cond: [
{ $eq: [{ $isArray: "$$q.answer" }, true] },
"$$q.answer",
["$$q.answer"]
]
},
as: "a",
in: {
$mergeObjects: [
"$$a",
{
m_IMG: {
$mergeObjects: [
"$$a.m_IMG",
{
img: {
$mergeObjects: [
"$$a.m_IMG.img",
{
shape: {
$cond: [
{ $eq: [{ $isArray: "$$a.m_IMG.img.shape" }, true] },
"$$a.m_IMG.img.shape",
["$$a.m_IMG.img.shape"]
]
}
}
]
}
}
]
}
}
]
}
}
}
}
]
}
}
}
}
}
])
Playground
From MongoDb version >= 4.4 you can use the $function operator to define custom functions to implement behavior not supported by the MongoDB Query Language. Try this:
db.collection.aggregate([
{ $unwind: "$questions" },
{
$addFields: {
"questions.answer": {
$function: {
body: function (answers) {
if (Array.isArray(answers)) {
answers.map(function (answer) {
if (!Array.isArray(answer.m_IMG.img.shape)) {
answer.m_IMG.img.shape = [answer.m_IMG.img.shape]
}
})
return answers;
} else {
if (!Array.isArray(answers.m_IMG.img.shape)) {
answers.m_IMG.img.shape = [answers.m_IMG.img.shape]
}
return [answers];
}
},
args: ["$questions.answer"],
lang: "js"
}
}
}
}
]);
Output:
/* 1 createdAt:3/29/2021, 5:57:13 PM*/
{
"_id" : ObjectId("6061c7a1e801471ae43210ae"),
"name" : "test",
"questions" : {
"headline" : "headline 1",
"answer" : [
{
"#id" : "001",
"m_IMG" : {
"type" : "06",
"img" : {
"#id" : "1111",
"shape" : [
{
"#src" : "/1_1.jpg",
"#type" : "Z05"
},
{
"#src" : "/1_2.jpg",
"#type" : "Z08"
}
]
}
},
"text" : "text1"
}
]
}
},
/* 2 createdAt:3/29/2021, 5:57:13 PM*/
{
"_id" : ObjectId("6061c7a1e801471ae43210ae"),
"name" : "test",
"questions" : {
"headline" : "Headline 2",
"answer" : [
{
"#id" : "001",
"m_IMG" : {
"#type" : "24",
"img" : {
"#id" : "1111",
"shape" : [
{
"#src" : "/2_1.jpg",
"#type" : "Z05"
}
]
},
"text" : "Test2"
}
},
{
"#id" : "002",
"m_IMG" : {
"#typeName" : "",
"#type" : "25",
"img" : {
"#id" : "2222",
"shape" : [
{
"#src" : "/2_1.jpg",
"#type" : "Z05"
},
{
"#src" : "2_2.jpg",
"#type" : "Z08"
}
]
}
},
"text" : "Test3"
}
]
}
},
/* 3 createdAt:3/29/2021, 5:57:13 PM*/
{
"_id" : ObjectId("6061c7a1e801471ae43210ae"),
"name" : "test",
"questions" : {
"headline" : "headline 3",
"answer" : [
{
"#id" : "003",
"m_IMG" : {
"#type" : "25",
"img" : {
"#id" : "1221",
"shape" : [
{
"#src" : "/2_6.jpg",
"#type" : "Z07"
}
]
},
"text" : "Test21"
}
}
]
}
}
Test data:
[
{
"name": "test",
"questions": [
{
"headline": "headline 1",
"answer": {
"#id": "001",
"m_IMG": {
"type": "06",
"img": {
"#id": "1111",
"shape": [
{
"#src": "/1_1.jpg",
"#type": "Z05"
},
{
"#src": "/1_2.jpg",
"#type": "Z08"
}
]
}
},
"text": "text1"
}
},
{
"headline": "Headline 2",
"answer": [
{
"#id": "001",
"m_IMG": {
"#type": "24",
"img": {
"#id": "1111",
"shape": {
"#src": "/2_1.jpg",
"#type": "Z05"
}
},
"text": "Test2"
}
},
{
"#id": "002",
"m_IMG": {
"#typeName": "",
"#type": "25",
"img": {
"#id": "2222",
"shape": [
{
"#src": "/2_1.jpg",
"#type": "Z05"
},
{
"#src": "2_2.jpg",
"#type": "Z08"
}
]
}
},
"text": "Test3"
}
]
},
{
"headline": "headline 3",
"answer": {
"#id": "003",
"m_IMG": {
"#type": "25",
"img": {
"#id": "1221",
"shape": {
"#src": "/2_6.jpg",
"#type": "Z07"
}
},
"text": "Test21"
}
}
}
]
}
]

JSON conversion using JOLT

I am trying to convert a JSON to different format using JOLT (using NiFi JoltTransformJson processor). For single JSON record, the JOLT am using is working fine in JOLT app demo whereas if i execute with multiple JSON records then I am not getting expected output in JOLT app demo. Could anyone correct me what additional changes I need to do in JOLT spec to handle multiple JSON records.
sample input json
[
{
"pool": {
"field": [
{
"name": "BillingDay",
"value": "12"
},
{
"name": "Custom1",
"value": "POOL_BASE_PLAN_3GB"
}
]
},
"usage": {
"version": "3",
"quota": {
"name": "POOL_TOP_UP_1GB_2",
"cid": "5764888998010953848"
}
},
"state": {
"version": "1",
"property": [
{
"name": "SMS_RO_TOP",
"value": "1"
},
{
"name": "BillingTimeStamp",
"value": "2020-06-12T01:00:05"
},
{
"name": "timereset",
"value": "2020-01-12T00:35:53"
}
]
}
},
{
"pool": {
"field": [
{
"name": "PoolID",
"value": "111100110000003505209"
},
{
"name": "BillingDay",
"value": "9"
}
]
},
"usage": {
"version": "3"
},
"state": {
"version": "1",
"property": [
{
"name": "BillingTimeStamp",
"value": "2020-06-09T01:00:05"
},
{
"name": "timereset",
"value": "2019-03-20T17:10:38"
}
]
}
}
]
JOLT using:
[
{
"operation": "modify-default-beta",
"spec": {
"state": {
"property": {
"name": "NOTAVAILABLE"
}
},
"usage": {
"quota": {
"name": "NOTAVAILABLE"
}
}
}
},
{
"operation": "shift",
"spec": {
"pool": {
"field": {
"*": {
"value": "pool_item.#(1,name)"
}
}
},
// remaining elements print as it is
"*": "&"
}
}
]
Expected output JSON:
[
{
"pool_item" : {
"BillingDay" : "12",
"Custom1" : "POOL_BASE_PLAN_3GB"
},
"usage" : {
"version" : "3",
"quota" : {
"name" : "POOL_TOP_UP_1GB_2",
"cid" : "5764888998010953848"
}
},
"state" : {
"version" : "1",
"property" : [ {
"name" : "SMS_RO_TOP",
"value" : "1"
}, {
"name" : "BillingTimeStamp",
"value" : "2020-06-12T01:00:05"
}, {
"name" : "timereset",
"value" : "2020-01-12T00:35:53"
} ]
}
},
{
"pool_item" : {
"BillingDay" : "9",
"PoolID" : "111100110000003505209"
},
"usage" : {
"version" : "3",
"quota" : {
"name" : "NOTAVAILABLE"
}
},
"state" : {
"version" : "1",
"property" : [ {
"name" : "SMS_RO_TOP",
"value" : "1"
}, {
"name" : "BillingTimeStamp",
"value" : "2020-06-12T01:00:05"
}, {
"name" : "timereset",
"value" : "2020-01-12T00:35:53"
} ]
}
}
]
This below jolt shift specification will work for your multiple json's in input array.
[
{
"operation": "shift",
"spec": {
"*": {
"pool": {
"field": {
"*": {
"value": "[&4].pool_item.#(1,name)"
}
}
},
"usage": "[&1].usage",
"state": "[&1].state"
}
}
}
]

Filter nested array with conditions based on multi-level object values and update them - MongoDB aggregate + update

Considering I have the following documents in a collection (ignoring the _id) :
[
{
"Id": "OP01",
"Sessions": [
{
"Id": "Session01",
"Conversations": [
{
"Id": "Conversation01",
"Messages": [
{
"Id": "Message01",
"Status": "read",
"Direction": "inbound"
},
{
"Id": "Message02",
"Status": "delivered",
"Direction": "internal"
},
{
"Id": "Message03",
"Status": "delivered",
"Direction": "inbound"
},
{
"Id": "Message04",
"Status": "sent",
"Direction": "outbound"
}
]
},
{
"Id": "Conversation02",
"Messages": [
{
"Id": "Message05",
"Status": "sent",
"Direction": "outbound"
}
]
}
]
},
{
"Id": "Session02",
"Conversations": [
{
"Id": "Conversation03",
"Messages": [
{
"Id": "Message06",
"Status": "read",
"Direction": "inbound"
},
{
"Id": "Message07",
"Status": "delivered",
"Direction": "internal"
}
]
},
{
"Id": "Conversation04",
"Messages": []
}
]
}
]
},
{
"Id": "OP02",
"Sessions": [
{
"Id": "Session03",
"Conversations": []
}
]
},
{
"Id": "OP03",
"Sessions": []
}
]
First query — aggregate (+$project)
I want to get the list of Messages grouped by their Conversations where:
Sessions.Id: "Session01"
and
Sessions.Conversations.Messages.Direction $in ["inbound", "outbound"]
and
Sessions.Conversations.Messages.Status $in ["sent", "delivered"]
The expected result is:
[
{
"Id": "Conversation01",
"Messages": [
{
"Id": "Message03",
"Status": "delivered",
"Direction": "inbound"
},
{
"Id": "Message04",
"Status": "sent",
"Direction": "outbound"
}
]
},
{
"Id": "Conversation02",
"Messages": [
{
"Id": "Message05",
"Status": "sent",
"Direction": "outbound"
}
]
}
]
A side note:
If on different documents (or on different Sessions) the Sessions.Id: "Session01" condition is verified ("Session01"is not an unique key), the document's Messages that match the other conditions should also be added.
The result output doesn't mention neither the document or Sessions levels.
Second query — update
I want to update the Sessions.Conversations.Messages.Status of all those messages (same condition as before) to "read".
The collection should have now the following documents:
Please note the changes on:
Sessions.Conversations.Messages.Id = "Message03"
Sessions.Conversations.Messages.Id = "Message04"
Sessions.Conversations.Messages.Id = "Message05"
at Sessions.Id = "Session01"
[
{
"Id": "OP01",
"Sessions": [
{
"Id": "Session01",
"Conversations": [
{
"Id": "Conversation01",
"Messages": [
{
"Id": "Message01",
"Status": "read",
"Direction": "inbound"
},
{
"Id": "Message02",
"Status": "delivered",
"Direction": "internal"
},
{
"Id": "Message03",
"Status": "read",
"Direction": "inbound"
},
{
"Id": "Message04",
"Status": "read",
"Direction": "outbound"
}
]
},
{
"Id": "Conversation02",
"Messages": [
{
"Id": "Message05",
"Status": "read",
"Direction": "outbound"
}
]
}
]
},
{
"Id": "Session02",
"Conversations": [
{
"Id": "Conversation03",
"Messages": [
{
"Id": "Message06",
"Status": "read",
"Direction": "inbound"
},
{
"Id": "Message07",
"Status": "delivered",
"Direction": "internal"
}
]
},
{
"Id": "Conversation04",
"Messages": []
}
]
}
]
},
{
"Id": "OP02",
"Sessions": [
{
"Id": "Session03",
"Conversations": []
}
]
},
{
"Id": "OP03",
"Sessions": []
}
]
How can I accomplish these results with an aggregate and update_one queries?
Here comes a visual explanation of both queries:
I have written the aggregation query
db.session.aggregate([
{
$unwind:"$Sessions"
},
{
$unwind:"$Sessions.Conversations"
},
{
$unwind:"$Sessions.Conversations.Messages"
},
{
$match:{
"Sessions.Id" : "Session01",
"Sessions.Conversations.Messages.Direction":{
$in:[
"inbound", "outbound"
]
},
"Sessions.Conversations.Messages.Status":{
$in:[
"sent", "delivered"
]
}
}
},
{
$group:{
"_id":"$Sessions.Conversations.Id",
"Messages":{
$push:"$Sessions.Conversations.Messages"
}
}
}
]).pretty()
Output
{
"_id" : "Conversation02",
"Messages" : [
{
"Id" : "Message05",
"Status" : "sent",
"Direction" : "outbound"
}
]
}
{
"_id" : "Conversation01",
"Messages" : [
{
"Id" : "Message03",
"Status" : "delivered",
"Direction" : "inbound"
},
{
"Id" : "Message04",
"Status" : "sent",
"Direction" : "outbound"
}
]
}
Now to Update the document:
I have used the positional-filters
db.session.update(
{},
{
$set:{
"Sessions.$[session].Conversations.$[].Messages.$[message].Status":"read"
}
},
{
"arrayFilters": [{"session.Id":"Session01"},{ "message.Id": "Message05" }]
}
)
This will update the status as read for "session.Id":"Session01" and "message.Id": "Message05"
Hope this will help you. :)
UPDATE
db.session.update(
{},
{
$set:{
"Sessions.$[session].Conversations.$[].Messages.$[message].Status":"read"
}
},
{
"arrayFilters": [
{
"session.Id":"Session01"
},
{
"message.Direction": {
$in :[
"inbound",
"outbound"
]
},
"message.Status": {
$in :[
"sent",
"delivered"
]
}
}
]
}
)

Mongodb query select embedded document

I have following Mongodb document. Would like to fetch document where participant = 'xxx' and (message.touserid = 'xxx' or message.fromuserid = 'xxx').
I am using following query but it is returning all messages instead of just one. Could you please let me know how to achieve this result?
{ "$and" : [ { "participants" : { "$regex" : "56d314a8e4b04d7f98cfd0c6"} , "$or" : [ { "messages.touserId" : "56d314a8e4b04d7f98cfd0c6"} , { "messages.formuserId" : "56d314a8e4b04d7f98cfd0c6"}]}]} fields: { "_id" : "0" , "product" : "0" , "participants" : "0" , "messages" : "0"}
{
"_id": {
"$oid": "574eb878027520c2158268d6"
},
"_class": "com.idearealty.product.shopchat.persistence.model.Discussion",
"participants": "56d314a8e4b04d7f98cfd0c6,56d5d48ee4b0cc330f512a47,56d9d599e4b0cc330f512aaa,57130299e4b08c554c1092c7,56841002eceefce22f455c7f",
"messages": [
{
"_id": {
"$oid": "574eb874027520c2158268d2"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d314a8e4b04d7f98cfd0c6",
"touser": "debopam_r",
"message": "Creating Discussion",
"isMute": false,
"index": 1,
"createDate": {
"$date": "2016-06-01T10:27:00.500Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:00.501Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb875027520c2158268d3"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d5d48ee4b0cc330f512a47",
"touser": "Raushan",
"message": "Creating Discussion",
"isMute": false,
"index": 2,
"createDate": {
"$date": "2016-06-01T10:27:01.295Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:01.295Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb875027520c2158268d4"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "56d9d599e4b0cc330f512aaa",
"touser": "anirbanshop1",
"message": "Creating Discussion",
"isMute": false,
"index": 3,
"createDate": {
"$date": "2016-06-01T10:27:01.962Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:01.962Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
},
{
"_id": {
"$oid": "574eb876027520c2158268d5"
},
"formuserId": "56841002eceefce22f455c7f",
"fromuser": "9674642375",
"touserId": "57130299e4b08c554c1092c7",
"touser": "dummyshop",
"message": "Creating Discussion",
"isMute": false,
"index": 4,
"createDate": {
"$date": "2016-06-01T10:27:02.574Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:02.574Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
}
],
"messageCount": 4,
"createDate": {
"$date": "2016-06-01T10:27:04.041Z"
},
"lastModifiedDate": {
"$date": "2016-06-01T10:27:04.041Z"
},
"createdBy": "9674642375",
"lastModifiedBy": "9674642375"
}
As this is a complex match on elements - $elemMatch cannot be used in this case,
so aggregation framework is a helper.
var match = {
$match : {
participants : /56d314a8e4b04d7f98cfd0c6/
}
}
var unwind = {
$unwind : "$messages"
}
var matchSecond = {
$match : {
$or : [{
"messages.touserId" : "56d314a8e4b04d7f98cfd0c6"
}, {
"messages.formuserId" : "56d314a8e4b04d7f98cfd0c6"
}
]
}
}
var projection = {
$project : {
_id : 0,
messages : 1
}
}
db.deb.aggregate([match, unwind, matchSecond, projection])
and output:
{
"messages" : {
"_id" : {
"oid" : "574eb874027520c2158268d2"
},
"formuserId" : "56841002eceefce22f455c7f",
"fromuser" : "9674642375",
"touserId" : "56d314a8e4b04d7f98cfd0c6",
"touser" : "debopam_r",
"message" : "Creating Discussion",
"isMute" : false,
"index" : 1.0,
"createDate" : {
"date" : "2016-06-01T10:27:00.500Z"
},
"lastModifiedDate" : {
"date" : "2016-06-01T10:27:00.501Z"
},
"createdBy" : "9674642375",
"lastModifiedBy" : "9674642375"
}
}