Aggregation and Condition in Mongodb
up vote
1
down vote
favorite
I am new to MongoDB. I have the following collection : CallLeg which contains the data in the following format
{
"_id" : ObjectId("5bf5504a937eb609c4d020e4"),
"startedAt" : ISODate("2018-11-21T17:50:45.909Z"),
"endedAt" : ISODate("2018-11-21T18:02:09.909Z"),
"cc" : "91",
"phone" : "1234567890",
"type" : "pstn",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
{
"_id" : ObjectId("5bf5504a937eb609c4d020e5"),
"startedAt" : ISODate("2018-11-21T17:50:10.110Z"),
"endedAt" : ISODate("2018-11-21T18:02:10.110Z"),
"cc" : "91",
"phone" : "0007654321",
"type" : "voip",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
I want to get the output as follows :
- If cid is same for 'n' objects, it should return those objects. Let's say it returns 2
- Then if
obj1hastype=pstnandobj2hastype=voipit should return answer asMIXED, ifobj1_type = obj2_type = voipit should returnVOIPand similar forpstnfor the samecid.
Hope I am clear with my question.
mongodb aggregation
add a comment |
up vote
1
down vote
favorite
I am new to MongoDB. I have the following collection : CallLeg which contains the data in the following format
{
"_id" : ObjectId("5bf5504a937eb609c4d020e4"),
"startedAt" : ISODate("2018-11-21T17:50:45.909Z"),
"endedAt" : ISODate("2018-11-21T18:02:09.909Z"),
"cc" : "91",
"phone" : "1234567890",
"type" : "pstn",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
{
"_id" : ObjectId("5bf5504a937eb609c4d020e5"),
"startedAt" : ISODate("2018-11-21T17:50:10.110Z"),
"endedAt" : ISODate("2018-11-21T18:02:10.110Z"),
"cc" : "91",
"phone" : "0007654321",
"type" : "voip",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
I want to get the output as follows :
- If cid is same for 'n' objects, it should return those objects. Let's say it returns 2
- Then if
obj1hastype=pstnandobj2hastype=voipit should return answer asMIXED, ifobj1_type = obj2_type = voipit should returnVOIPand similar forpstnfor the samecid.
Hope I am clear with my question.
mongodb aggregation
This is what I have tried so far :db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }]. But unable to build query ahead.
– Aniket Maithani
2 days ago
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am new to MongoDB. I have the following collection : CallLeg which contains the data in the following format
{
"_id" : ObjectId("5bf5504a937eb609c4d020e4"),
"startedAt" : ISODate("2018-11-21T17:50:45.909Z"),
"endedAt" : ISODate("2018-11-21T18:02:09.909Z"),
"cc" : "91",
"phone" : "1234567890",
"type" : "pstn",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
{
"_id" : ObjectId("5bf5504a937eb609c4d020e5"),
"startedAt" : ISODate("2018-11-21T17:50:10.110Z"),
"endedAt" : ISODate("2018-11-21T18:02:10.110Z"),
"cc" : "91",
"phone" : "0007654321",
"type" : "voip",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
I want to get the output as follows :
- If cid is same for 'n' objects, it should return those objects. Let's say it returns 2
- Then if
obj1hastype=pstnandobj2hastype=voipit should return answer asMIXED, ifobj1_type = obj2_type = voipit should returnVOIPand similar forpstnfor the samecid.
Hope I am clear with my question.
mongodb aggregation
I am new to MongoDB. I have the following collection : CallLeg which contains the data in the following format
{
"_id" : ObjectId("5bf5504a937eb609c4d020e4"),
"startedAt" : ISODate("2018-11-21T17:50:45.909Z"),
"endedAt" : ISODate("2018-11-21T18:02:09.909Z"),
"cc" : "91",
"phone" : "1234567890",
"type" : "pstn",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
{
"_id" : ObjectId("5bf5504a937eb609c4d020e5"),
"startedAt" : ISODate("2018-11-21T17:50:10.110Z"),
"endedAt" : ISODate("2018-11-21T18:02:10.110Z"),
"cc" : "91",
"phone" : "0007654321",
"type" : "voip",
"status" : true,
"channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
"cost" : 0,
"duration" : 0,
"cid" : "ABCDEFGH"
}
I want to get the output as follows :
- If cid is same for 'n' objects, it should return those objects. Let's say it returns 2
- Then if
obj1hastype=pstnandobj2hastype=voipit should return answer asMIXED, ifobj1_type = obj2_type = voipit should returnVOIPand similar forpstnfor the samecid.
Hope I am clear with my question.
mongodb aggregation
mongodb aggregation
edited 2 days ago
mickl
10.2k51435
10.2k51435
asked 2 days ago
Aniket Maithani
7810
7810
This is what I have tried so far :db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }]. But unable to build query ahead.
– Aniket Maithani
2 days ago
add a comment |
This is what I have tried so far :db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }]. But unable to build query ahead.
– Aniket Maithani
2 days ago
This is what I have tried so far :
db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }] . But unable to build query ahead.– Aniket Maithani
2 days ago
This is what I have tried so far :
db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }] . But unable to build query ahead.– Aniket Maithani
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
You can use below aggregation:
db.CallLeg.aggregate([
{
$group: {
_id: "$cid",
objects: { $push: "$$ROOT" }
}
},
{
$match: { objects: { $size: 2 } }
},
{
$addFields: {
answer: {
$switch: {
branches: [
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "voip" ] } } } ] } , then: "voip" },
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "pstn" ] } } } ] } , then: "pstn" },
],
default: "MIXED"
}
}
}
}
])
Basically you need to $group by cid to compare multiple documents with each other. You can also add $match before $group if you need to analyze only one cid. Then you can use $size to check the number of "same" objects. In the last stage you need to compare the elements in objects array. You can use $map to get an array of boolean values which will indicate how many voip and pstns values you have. Then you need $allElementsTrue to check if you have one type for all items. Everything can be placed inside $switch to define last, default branch which is MIXED
mickl, while trying your query I get the following response :"errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :Unrecognized pipeline stage name: '$addFields
– Aniket Maithani
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
|
show 4 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
You can use below aggregation:
db.CallLeg.aggregate([
{
$group: {
_id: "$cid",
objects: { $push: "$$ROOT" }
}
},
{
$match: { objects: { $size: 2 } }
},
{
$addFields: {
answer: {
$switch: {
branches: [
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "voip" ] } } } ] } , then: "voip" },
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "pstn" ] } } } ] } , then: "pstn" },
],
default: "MIXED"
}
}
}
}
])
Basically you need to $group by cid to compare multiple documents with each other. You can also add $match before $group if you need to analyze only one cid. Then you can use $size to check the number of "same" objects. In the last stage you need to compare the elements in objects array. You can use $map to get an array of boolean values which will indicate how many voip and pstns values you have. Then you need $allElementsTrue to check if you have one type for all items. Everything can be placed inside $switch to define last, default branch which is MIXED
mickl, while trying your query I get the following response :"errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :Unrecognized pipeline stage name: '$addFields
– Aniket Maithani
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
|
show 4 more comments
up vote
1
down vote
You can use below aggregation:
db.CallLeg.aggregate([
{
$group: {
_id: "$cid",
objects: { $push: "$$ROOT" }
}
},
{
$match: { objects: { $size: 2 } }
},
{
$addFields: {
answer: {
$switch: {
branches: [
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "voip" ] } } } ] } , then: "voip" },
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "pstn" ] } } } ] } , then: "pstn" },
],
default: "MIXED"
}
}
}
}
])
Basically you need to $group by cid to compare multiple documents with each other. You can also add $match before $group if you need to analyze only one cid. Then you can use $size to check the number of "same" objects. In the last stage you need to compare the elements in objects array. You can use $map to get an array of boolean values which will indicate how many voip and pstns values you have. Then you need $allElementsTrue to check if you have one type for all items. Everything can be placed inside $switch to define last, default branch which is MIXED
mickl, while trying your query I get the following response :"errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :Unrecognized pipeline stage name: '$addFields
– Aniket Maithani
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
|
show 4 more comments
up vote
1
down vote
up vote
1
down vote
You can use below aggregation:
db.CallLeg.aggregate([
{
$group: {
_id: "$cid",
objects: { $push: "$$ROOT" }
}
},
{
$match: { objects: { $size: 2 } }
},
{
$addFields: {
answer: {
$switch: {
branches: [
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "voip" ] } } } ] } , then: "voip" },
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "pstn" ] } } } ] } , then: "pstn" },
],
default: "MIXED"
}
}
}
}
])
Basically you need to $group by cid to compare multiple documents with each other. You can also add $match before $group if you need to analyze only one cid. Then you can use $size to check the number of "same" objects. In the last stage you need to compare the elements in objects array. You can use $map to get an array of boolean values which will indicate how many voip and pstns values you have. Then you need $allElementsTrue to check if you have one type for all items. Everything can be placed inside $switch to define last, default branch which is MIXED
You can use below aggregation:
db.CallLeg.aggregate([
{
$group: {
_id: "$cid",
objects: { $push: "$$ROOT" }
}
},
{
$match: { objects: { $size: 2 } }
},
{
$addFields: {
answer: {
$switch: {
branches: [
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "voip" ] } } } ] } , then: "voip" },
{ case: { $allElementsTrue: [
{ $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "pstn" ] } } } ] } , then: "pstn" },
],
default: "MIXED"
}
}
}
}
])
Basically you need to $group by cid to compare multiple documents with each other. You can also add $match before $group if you need to analyze only one cid. Then you can use $size to check the number of "same" objects. In the last stage you need to compare the elements in objects array. You can use $map to get an array of boolean values which will indicate how many voip and pstns values you have. Then you need $allElementsTrue to check if you have one type for all items. Everything can be placed inside $switch to define last, default branch which is MIXED
edited yesterday
answered 2 days ago
mickl
10.2k51435
10.2k51435
mickl, while trying your query I get the following response :"errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :Unrecognized pipeline stage name: '$addFields
– Aniket Maithani
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
|
show 4 more comments
mickl, while trying your query I get the following response :"errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :Unrecognized pipeline stage name: '$addFields
– Aniket Maithani
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
mickl, while trying your query I get the following response :
"errmsg" : "bad query: BadValue: unknown top level operator: $expr",– Aniket Maithani
yesterday
mickl, while trying your query I get the following response :
"errmsg" : "bad query: BadValue: unknown top level operator: $expr",– Aniket Maithani
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
@AniketMaithani you must be using MongoDB in version lower that 3.6, but that's not a problem, modified my answer, you can verify it here: mongoplayground.net/p/cI1aH1Wd9CX
– mickl
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :
Unrecognized pipeline stage name: '$addFields– Aniket Maithani
yesterday
mickl, thanks for your answer. Yes, I am using mongo 3.2.21 . Now I get the following error :
Unrecognized pipeline stage name: '$addFields– Aniket Maithani
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
Any chance to upgrade to 3.4 ?
– mickl
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
yesterday
|
show 4 more comments
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413227%2faggregation-and-condition-in-mongodb%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This is what I have tried so far :
db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }]. But unable to build query ahead.– Aniket Maithani
2 days ago