MongoDB Aggregation - Creating new arrays from a given array - mongodb

i wish to create new arrays from a given array based on my aggregation results, the desired outcome from the following doc is to split the array into new arrays where the split point is the action "start"
{
"_id" : "5f851b06b08ab4b1f916c14841d4bbba",
"actions" : [
{
"action" : "start",
"datetime" : 1525692527345.0
},
{
"action" : "scrolled",
"datetime" : 1525692545966.0
},
{
"action" : "scrolled",
"datetime" : 1525692545983.0
},
{
"action" : "click",
"datetime" : 1525692545999.0
},
{
"action" : "start",
"datetime" : 1525693343877.0
},
{
"action" : "mousemove",
"datetime" : 1525693351075.0
},
{
"action" : "mousemove",
"datetime" : 1525693351117.0
},
{
"action" : "scrolled",
"datetime" : 1525693351212.0
},
{
"action": "scrolled",
"datetime": 1525693354026.0
},
{
"action": "scrolled",
"datetime": 1525693354126.0
}
]
}
so next i should have a document that looks like this:
{
"_id": "5f851b06b08ab4b1f916c14841d4bbba",
"session1": [
{
"action": "start",
"datetime": 1525692527345.0
},
{
"action": "scrolled",
"datetime": 1525692545966.0
},
{
"action": "scrolled",
"datetime": 1525692545983.0
},
{
"action": "click",
"datetime": 1525692545999.0
}
],
"session2": [
{
"action": "start",
"datetime": 1525693343877.0
},
{
"action": "mousemove",
"datetime": 1525693351075.0
},
{
"action": "mousemove",
"datetime": 1525693351118.0
},
{
"action": "mousemove",
"datetime": 1525693351119.0
},
{
"action": "mousemove",
"datetime": 1525693351121.0
},
{
"action": "scrolled",
"datetime": 1525693351212.0
},
{
"action": "scrolled",
"datetime": 1525693354026.0
},
{
"action": "scrolled",
"datetime": 1525693354126.0
}
]
}
the session1, session2 field name can be anything it's just for the sake of showing the desired result.
any ideas how to add this to my existing aggregation pipeline?
db.collection.aggregate(
[
{
"$match" : {
"action" : {
"$exists" : true
},
"domain" : "domain.com"
}
},
{
"$unwind" : "$action"
},
{
"$sort" : {
"action.datetime" : 1.0
}
},
{
"$group" : {
"_id" : "$id",
"count" : {
"$sum" : 1.0
},
"actions" : {
"$addToSet" : {
"id" : "$id",
"action" : "$action.action",
"datetime" : "$action.datetime"
}
}
}
},
{
"$unwind" : "$actions"
},
{
"$sort" : {
"actions.datetime" : 1.0
}
},
{
"$group" : {
"_id" : "$actions.id",
"count" : {
"$sum" : 1.0
},
"actions" : {
"$push" : {
"action" : "$actions.action",
"datetime" : "$actions.datetime"
}
}
}
},
{
"$match" : {
"count" : {
"$gt" : 1.0
}
}
}
],
{
"allowDiskUse" : true
}
);
Thanks for looking!

Related

MongoDB Query that will $project document values in horizontal format

Im trying to create a query that will project or show the field in HORIZONTAL format. Below is my sample collection and the expected output. BTW, Im also using jaspersoft studio to create the report but i think my output should be done in mongodb query. Hope someone can help. Thanks!
"_id" : ObjectId("60ddc6f44c893c117141e9b9"),
"observationvalues" : [
{
"_id" : ObjectId("60ddc6f44c893c117141e9c3"),
"name" : "Systolic BP",
"resultvalue" : "88.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9c2"),
"name" : "Diastolic BP",
"resultvalue" : "66.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9c1"),
"name" : "Weight",
"resultvalue" : "90.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9c5"),
"name" : "Height",
"resultvalue" : null
}
],
"createdat" : ISODate("2021-07-01T13:45:24.679Z"),
"modifiedat" : ISODate("2021-07-01T13:45:24.679Z"),
"statusflag" : "A"
"_id" : ObjectId("60ddc6f44c893c117141e8b8"),
"observationvalues" : [
{
"_id" : ObjectId("60ddc6f44c893c117141e9b3"),
"name" : "Systolic BP",
"resultvalue" : "84.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9b2"),
"name" : "Diastolic BP",
"resultvalue" : "63.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9b1"),
"name" : "Weight",
"resultvalue" : "99.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9b5"),
"name" : "Height",
"resultvalue" : 172.00
}
],
"createdat" : ISODate("2021-07-02T13:45:24.679Z"),
"modifiedat" : ISODate("2021-07-02T13:45:24.679Z"),
"statusflag" : "A"
"_id" : ObjectId("60ddc6f44c893c117141e7b7"),
"observationvalues" : [
{
"_id" : ObjectId("60ddc6f44c893c117141e9a3"),
"name" : "Systolic BP",
"resultvalue" : "81.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9a2"),
"name" : "Diastolic BP",
"resultvalue" : "65.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9a1"),
"name" : "Weight",
"resultvalue" : "96.00"
},
{
"_id" : ObjectId("60ddc6f44c893c117141e9a5"),
"name" : "Height",
"resultvalue" : 165.00
}
],
"createdat" : ISODate("2021-07-03T13:45:24.679Z"),
"modifiedat" : ISODate("2021-07-03T13:45:24.679Z"),
"statusflag" : "A",
The expected Output will be:
{"createdat" : "2021-07-01T13:45:24.679Z", "Systolic BP" : 88.00 ,"Diastolic BP" : 66.00 ,"Weight": 90.00 ,"Height":null }
{"createdat" : "2021-07-01T13:45:24.679Z", "Systolic BP" : 84.00 ,"Diastolic BP" : 63.00 ,"Weight": 99.00 ,"Height":172.00 }
{"createdat" : "2021-07-03T13:45:24.679Z", "Systolic BP" : 81.00 ,"Diastolic BP" : 65.00 ,"Weight": 96.00 ,"Height":165.00 }
I have created my query but it is not having the output in one line grouped for each createdat field
{
$project : {
_id: {
"systolic": {"$cond": [ { "$eq": ["$name","Systolic BP" ] }, "$resultvalue","" ] },
"diastolic": {"$cond": [ { "$eq": ["$name","Diastolic BP" ] }, "$resultvalue","" ] },
"weight": {"$cond": [ { "$eq": ["$name","Weight" ] }, "$resultvalue","" ] },
"height": {"$cond": [ { "$eq": ["$name","Height" ] }, "$resultvalue","" ] },
"create": "$createdat"
}
}
},
Your expected data output could be done like this: playground
[
{
"$project": {
"createdat": 1,
"rows": {
"$arrayToObject": {
"$map": {
"input": "$observationvalues",
"in": {
"k": "$$this.name",
"v": {
"$convert": {
"input": "$$this.resultvalue",
"to": "double",
"onError": null,
"onNull": null
}
}
}
}
}
}
}
},
{
"$addFields": {
"rows.create": "$createdat"
}
},
{
"$replaceRoot": {
"newRoot": "$rows"
}
},
{
"$match": {
"Systolic BP": 84.00
}
}
]
To get them in one line you should look for some JSON formater.

Merge mongodb aggregation results of unread messages count per conversation member into document

I want to aggregate unread messages count per member in a conversation group and seems my aggregation pipeline is working correctly, but, I don't know how to achieve the following results.
Please check the example.
Thread documents
/* 1 */
{
"_id" : ObjectId("60d4efa6a95f446051f31492"),
"latestMessage" : "Voluptatem eos officiis optio dolor est et.",
"type" : "FEED",
"users" : [
{
"_id" : ObjectId("60d4efa6a95f446051f31491"),
"displayName" : "Monique Connelly II"
},
{
"_id" : ObjectId("60d4efa6a95f446051f31490"),
"displayName" : "Ivory Jacobson DDS"
},
{
"_id" : ObjectId("60d4efa6a95f446051f3148f"),
"displayName" : "Ron Weimann"
}
],
"createdBy" : "60d4efa6a95f446051f3148f",
"createdAt" : ISODate("2021-06-24T20:48:38.537Z"),
"modifiedAt" : ISODate("2021-06-24T20:48:38.620Z"),
}
/* 2 */
{
"_id" : ObjectId("60d4efa6a95f446051f31493"),
"type" : "CONVERSATION",
"users" : [
{
"_id" : ObjectId("60d4efa6a95f446051f31491"),
"displayName" : "Monique Connelly II"
},
{
"_id" : ObjectId("60d4efa6a95f446051f31490"),
"displayName" : "Ivory Jacobson DDS"
},
{
"_id" : ObjectId("60d4efa6a95f446051f3148f"),
"displayName" : "Ron Weimann"
}
],
"createdBy" : "60d4efa6a95f446051f3148f",
"createdAt" : ISODate("2021-06-24T20:48:38.569Z"),
"modifiedAt" : ISODate("2021-06-24T20:48:38.569Z"),
}
Message documents
/* 1 */
{
"_id" : ObjectId("60d4efa6a95f446051f31494"),
"content" : "Itaque rerum facere neque fuga aspernatur dolorum.",
"deleted" : false,
"threadId" : ObjectId("60d4efa6a95f446051f31492"),
"type" : "TEXT",
"thread" : {
"$ref" : "threads",
"$id" : ObjectId("60d4efa6a95f446051f31492")
},
"readBy" : [
ObjectId("60d4efa6a95f446051f3148f")
],
"attributes" : [],
"createdBy" : "60d4efa6a95f446051f3148f",
"createdAt" : ISODate("2021-06-24T20:48:38.598Z"),
"modifiedAt" : ISODate("2021-06-24T20:48:38.598Z"),
}
/* 2 */
{
"_id" : ObjectId("60d4efa6a95f446051f31495"),
"content" : "Nisi suscipit iste magni voluptatem.",
"deleted" : false,
"threadId" : ObjectId("60d4efa6a95f446051f31492"),
"type" : "TEXT",
"thread" : {
"$ref" : "threads",
"$id" : ObjectId("60d4efa6a95f446051f31492")
},
"readBy" : [
ObjectId("60d4efa6a95f446051f3148f")
],
"attributes" : [],
"createdBy" : "60d4efa6a95f446051f3148f",
"createdAt" : ISODate("2021-06-24T20:48:38.610Z"),
"modifiedAt" : ISODate("2021-06-24T20:48:38.610Z"),
}
and more...
My aggregation pipeline
db.threads.aggregate([
{ "$lookup": { "from": "messages", "localField": "_id", "foreignField": "threadId", "as": "message"}},
{ "$unwind": "$message" },
{ "$unwind": "$users" },
{ "$unwind": "$message.readBy" },
{ "$group": {
"_id": {
"user_id": "$users._id",
"thread_id": "$_id",
},
"unread_messages": {
"$sum": {
"$cond": [
{ "$ne": [ "$users._id", "$message.readBy" ] },
1,
0
]
}
}
}},
// { "$replaceRoot": { "newRoot": { "$mergeObjects": ["$_id", { "count": "$unread_messages" }]} } }
])
Aggregation results
{
"_id" : {
"user_id" : ObjectId("60d4efa6a95f446051f31491"),
"thread_id" : ObjectId("60d4efa6a95f446051f31492")
},
"unread_messages" : 4.0
},
{
"_id" : {
"user_id" : ObjectId("60d4efa6a95f446051f3148f"),
"thread_id" : ObjectId("60d4efa6a95f446051f31492")
},
"unread_messages" : 4.0
},
{
"_id" : {
"user_id" : ObjectId("60d4efa6a95f446051f31490"),
"thread_id" : ObjectId("60d4efa6a95f446051f31492")
},
"unread_messages" : 4.0
}
Results are partially OK, but, I want to keep my original structure of a document and copy aggregation results accordingly to the thread id back to the original document
I would be very grateful if you help me with the aggregation pipeline
Expected results
{
"_id": ObjectId("60d4efa6a95f446051f31492"),
"latestMessage": "Voluptatem eos officiis optio dolor est et.",
"type": "LISTING",
"users": [{
"_id": ObjectId("60d4efa6a95f446051f31491"),
"displayName": "Monique Connelly II"
},
{
"_id": ObjectId("60d4efa6a95f446051f31490"),
"displayName": "Ivory Jacobson DDS"
},
{
"_id": ObjectId("60d4efa6a95f446051f3148f"),
"displayName": "Ron Weimann"
}
],
"createdBy": "60d4efa6a95f446051f3148f",
"createdAt": ISODate("2021-06-24T20:48:38.537Z"),
"modifiedAt": ISODate("2021-06-24T20:48:38.620Z"),
"message": [...],
"stats": [{
"_id": {
"user_id": ObjectId("60d4efa6a95f446051f31491"),
"thread_id": ObjectId("60d4efa6a95f446051f31492")
},
"unread_messages": 4.0
},
{
"_id": {
"user_id": ObjectId("60d4efa6a95f446051f3148f"),
"thread_id": ObjectId("60d4efa6a95f446051f31492")
},
"unread_messages": 4.0
},
{
"_id": {
"user_id": ObjectId("60d4efa6a95f446051f31490"),
"thread_id": ObjectId("60d4efa6a95f446051f31492")
},
"unread_messages": 4.0
}
]
}
I post a solution that works perfectly for my case with $first + $replateRoot operations.
Final results have different ids as not in the first post that is because I re-created documents
db.threads.aggregate([
{ "$lookup": { "from": "messages", "localField": "_id", "foreignField": "threadId", "as": "message"}},
{ "$unwind": "$message" },
{ "$unwind": "$users" },
{ "$unwind": "$message.readBy" },
{ "$group": {
"_id": {
"user_id": "$users._id",
"thread_id": "$_id",
},
"thread": {
"$first": "$$ROOT"
},
"unread_messages": {
"$sum": {
"$cond": [
{ "$ne": [ "$users._id", "$message.readBy" ] },
1,
0
]
}
}
}},
{ "$group": {
"_id": "$_id.thread_id",
"thread": { "$first": "$thread" },
"stats": {
"$push": {
"userId": "$_id.user_id",
"unreadMessages": "$unread_messages"
}
}
}},
{ "$replaceRoot": { "newRoot": { "$mergeObjects": ["$thread", { stats: "$stats" }]} } }
])
Final results
/* 1 */
{
"_id" : ObjectId("60d574e242e59a48b886c586"),
"latestMessage" : "Molestias quo quod occaecati exercitationem veniam eaque.",
"type" : "LISTING",
"users" : {
"_id" : ObjectId("60d574e242e59a48b886c584"),
"displayName" : "Meggan Vandervort"
},
"unreadMessages" : NumberLong(0),
"createdBy" : "60d574e242e59a48b886c582",
"createdAt" : ISODate("2021-06-25T06:17:06.547Z"),
"modifiedAt" : ISODate("2021-06-25T06:17:06.617Z")
"message" : {
"_id" : ObjectId("60d574e242e59a48b886c58d"),
"content" : "Velit dolores vel.",
"deleted" : false,
"threadId" : ObjectId("60d574e242e59a48b886c586"),
"type" : "TEXT",
"thread" : {
"$ref" : "threads",
"$id" : ObjectId("60d574e242e59a48b886c586")
},
"readBy" : ObjectId("60d574e242e59a48b886c582"),
"attributes" : [],
"createdBy" : "60d574e242e59a48b886c582",
"createdAt" : ISODate("2021-06-25T06:17:06.595Z"),
"modifiedAt" : ISODate("2021-06-25T06:17:06.595Z")
},
"stats" : [
{
"userId" : ObjectId("60d574e242e59a48b886c584"),
"unreadessages" : 6.0
},
{
"userId" : ObjectId("60d574e242e59a48b886c583"),
"unreadessages" : 6.0
},
{
"userId" : ObjectId("60d574e242e59a48b886c582"),
"unreadessages" : 6.0
}
]
}
and more...

Group and Merge array of objects

I am struggling around with the aggregation pipeline feature from MongoDB.
So far the output for one result looks like this:
{
"type": "inbound",
"sender": "postAG",
"receiver": "maxMusterMan",
"datetime": "20191125",
"info": [
{
"q": "A",
"value": "5",
"name": null,
"plz": 1234
},
{
"q": "B",
"value": "AS",
"name": "ABS",
"plz": null
},
{
"q": "A",
"value": "5",
"name": "aa",
"plz": null
},
... more objects
]
}
The final result should look like:
{
"type": "inbound",
"sender": "postAG",
"receiver": "maxMusterMan",
"datetime": "20191125",
"info": [
{
"q": "A",
"value": "0",
"name": "aa",
"plz": 1234
},
{
"q": "B",
"value": "AS",
"name": "ABS"
}
]
}
So in a nutshell, I want to group the values from the array field info by the "q" field and merge the objects (newer one overwrites the old value).
Further I would like to remove all the values with value "" or null;
There are more fields in the real payload, so I would like to avoid to add a $cond for each field of the object.
Some approaches so far from my side:
for the cleanup, use a UDF, but this is not possible in the pipeline.
use map-reduce for the group and merge, not available in the pipeline.
Please consider that the input file is the output from the several pipeline steps.
So I can not just use map-reduce alone, first I need the pipeline too.
My idea was to create two views, first will do the pipeline stuff and second map-reduce, is this a good solution?
Thx
Andreas
I didn't really understand from your explanation if you can or cannot use map-reduce.
However assuming you can't and you have to 'concat' the pipelines there is no 'generic' workaround for multiple fields - you have to create a condition for each in the pipeline.
With that said here is a working pipeline:
db.collection.aggregate(
[
{
"$unwind" : "$info"
},
{
"$group" : {
"_id" : "$info.q",
"type" : {
"$first" : "$type"
},
"sender" : {
"$first" : "$sender"
},
"receiver" : {
"$first" : "$receiver"
},
"datetime" : {
"$first" : "$datetime"
},
"values" : {
"$push" : "$info.value"
},
"names" : {
"$push" : "$info.name"
},
"plz" : {
"$push" : "$info.plz"
}
}
},
{
"$project" : {
"_id" : 1.0,
"type" : 1.0,
"sender" : 1.0,
"receiver" : 1.0,
"datetime" : 1.0,
"values" : {
"$filter" : {
"input" : "$values",
"as" : "curr",
"cond" : {
"$or" : [
{
"$ne" : [
"$$curr",
null
]
},
{
"$ne" : [
"$$curr",
""
]
}
]
}
}
},
"names" : {
"$filter" : {
"input" : "$names",
"as" : "curr",
"cond" : {
"$or" : [
{
"$ne" : [
"$$curr",
null
]
},
{
"$ne" : [
"$$curr",
""
]
}
]
}
}
},
"plz" : {
"$filter" : {
"input" : "$plz",
"as" : "curr",
"cond" : {
"$or" : [
{
"$ne" : [
"$$curr",
null
]
},
{
"$ne" : [
"$$curr",
""
]
}
]
}
}
}
}
},
{
"$project" : {
"sender" : 1.0,
"receiver" : 1.0,
"datetime" : 1.0,
"type" : 1.0,
"_id" : 1.0,
"value" : {
"$cond" : {
"if" : {
"$gt" : [
{
"$size" : "$values"
},
0.0
]
},
"then" : {
"$arrayElemAt" : [
"$values",
-1.0
]
},
"else" : null
}
},
"name" : {
"$cond" : {
"if" : {
"$gt" : [
{
"$size" : "$names"
},
0.0
]
},
"then" : {
"$arrayElemAt" : [
"$names",
-1.0
]
},
"else" : null
}
},
"plz" : {
"$cond" : {
"if" : {
"$gt" : [
{
"$size" : "$plz"
},
0.0
]
},
"then" : {
"$arrayElemAt" : [
"$plz",
-1.0
]
},
"else" : null
}
}
}
},
{
"$addFields" : {
"infoArray" : [
{
"k" : "type",
"v" : "$_id"
},
{
"k" : "value",
"v" : "$value"
},
{
"k" : "name",
"v" : "$name"
},
{
"k" : "plz",
"v" : "$plz"
}
]
}
},
{
"$addFields" : {
"info" : {
"$arrayToObject" : {
"$filter" : {
"input" : "$infoArray",
"as" : "curr",
"cond" : {
"$ne" : [
"$$curr.v",
null
]
}
}
}
}
}
},
{
"$group" : {
"_id" : null,
"type" : {
"$first" : "$type"
},
"sender" : {
"$first" : "$sender"
},
"receiver" : {
"$first" : "$receiver"
},
"datetime" : {
"$first" : "$datetime"
},
"info" : {
"$push" : "$info"
}
}
}
]
)

how to sort an array in a nested array which is located under an object in mongodb

I have a collection data like below.
{
"name": "Devices",
"exten": {
"parameters": [{
"name": "Date",
"value": ["5","2"]
}, {
"name": "Time",
"value": ["2"]
}, {
"name": "Season",
"value": ["6"]
}
]
}
}
I want to take all data which is name "Devices" and sort by first index of "Value" which is parameter name is "Date"
ex: mongo will get
name = "devices"
exten.parameters.name = "Date"
will sort it by
exten.parameters.value[0]
in this example it will be sorted by "5".
below query returns 0 record.
db.brand.aggregate(
{ $match: {
"name" : "Devices"
}},
{ $unwind: "$exten.parameters" },
{ $match: {
'exten.parameters.name': 'Date'
}},
{ $sort: {
'exten.parameters.value': -1
}}
)
The following query can get us the expected output:
db.collection.aggregate([
{
$match:{
"name":"Devices"
}
},
{
$unwind:"$exten.parameters"
},
{
$match:{
"exten.parameters.name":"Date"
}
},
{
$project:{
"name":1,
"exten":1,
"firstParam":{
$arrayElemAt:["$exten.parameters.value",0]
}
}
},
{
$sort:{
"firstParam":1
}
},
{
$project:{
"firstParam":0
}
}
]).pretty()
Data set:
{
"_id" : ObjectId("5da02fb86472ba670fd8c159"),
"name" : "Devices",
"exten" : {
"parameters" : [
{
"name" : "Date",
"value" : [
"5",
"2"
]
},
{
"name" : "Date",
"value" : [
"2",
"7"
]
},
{
"name" : "Time",
"value" : [
"2"
]
},
{
"name" : "Season",
"value" : [
"6"
]
}
]
}
}
Output:
{
"_id" : ObjectId("5da02fb86472ba670fd8c159"),
"name" : "Devices",
"exten" : {
"parameters" : {
"name" : "Date",
"value" : [
"2",
"7"
]
}
}
}
{
"_id" : ObjectId("5da02fb86472ba670fd8c159"),
"name" : "Devices",
"exten" : {
"parameters" : {
"name" : "Date",
"value" : [
"5",
"2"
]
}
}
}

mongodb aggregation match multiple $and on the same field

i have a document like this :
{
"ExtraFields" : [
{
"value" : "print",
"fieldID" : ObjectId("5535627631efa0843554b0ea")
},
{
"value" : "14",
"fieldID" : ObjectId("5535627631efa0843554b0eb")
},
{
"value" : "POLYE",
"fieldID" : ObjectId("5535627631efa0843554b0ec")
},
{
"value" : "30",
"fieldID" : ObjectId("5535627631efa0843554b0ed")
},
{
"value" : "0",
"fieldID" : ObjectId("5535627631efa0843554b0ee")
},
{
"value" : "0",
"fieldID" : ObjectId("5535627731efa0843554b0ef")
},
{
"value" : "0",
"fieldID" : ObjectId("5535627831efa0843554b0f0")
},
{
"value" : "42",
"fieldID" : ObjectId("5535627831efa0843554b0f1")
},
{
"value" : "30",
"fieldID" : ObjectId("5535627831efa0843554b0f2")
},
{
"value" : "14",
"fieldID" : ObjectId("5535627831efa0843554b0f3")
},
{
"value" : "19",
"fieldID" : ObjectId("5535627831efa0843554b0f4")
}
],
"id" : ObjectId("55369e60733e4914550832d0"), "title" : "A product"
}
what i want is to match one or more sets from the ExtraFields array. For example, all the products that contain the values print and 30. Since a value may be found in more than one fieldID (like 0 or true) we need to create a set like
WHERE (fieldID : ObjectId("5535627631efa0843554b0ea"), value : "print")
Where i'm having problems is when querying more than one fields. The pipeline i came up with is :
db.products.aggregate([
{'$unwind': '$ExtraFields'},
{
'$match': {
'$and': [{
'$and': [{'ExtraFields.value': {'$in': ["A52A2A"]}}, {
'ExtraFields.fieldID': ObjectId("5535627631efa0843554b0ea")
}]
}
,
{
'$and': [{'ExtraFields.value': '14'}, {'ExtraFields.fieldID': ObjectId("5535627631efa0843554b0eb")}]
}
]
}
},
]);
This returns zero results, but this is what i want to do in theory. Match all items that contain set 1 AND all that contain set 2.
The end result should look like a faceted search output :
[
{
"_id" : {
"values" : "18",
"fieldID" : ObjectId("5535627831efa0843554b0f3")
},
"count" : 2
},
{
"_id" : {
"values" : "33",
"fieldID" : ObjectId("5535627831efa0843554b0f2")
},
"count" : 1
}
]
Any ideas?
You could try the following aggregation pipeline
db.products.aggregate([
{
"$match": {
"ExtraFields.value": { "$in": ["A52A2A", "14"] },
"ExtraFields.fieldID": {
"$in": [
ObjectId("5535627631efa0843554b0ea"),
ObjectId("5535627631efa0843554b0eb")
]
}
}
},
{
"$unwind": "$ExtraFields"
},
{
"$match": {
"ExtraFields.value": { "$in": ["A52A2A", "14"] },
"ExtraFields.fieldID": {
"$in": [
ObjectId("5535627631efa0843554b0ea"),
ObjectId("5535627631efa0843554b0eb")
]
}
}
},
{
"$group": {
"_id": {
"value": "$ExtraFields.value",
"fieldID": "$ExtraFields.fieldID"
},
"count": {
"$sum": 1
}
}
}
])
With the sample document provided, this gives the output:
/* 1 */
{
"result" : [
{
"_id" : {
"value" : "14",
"fieldID" : ObjectId("5535627631efa0843554b0eb")
},
"count" : 1
}
],
"ok" : 1
}