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 obj1 has type=pstn and obj2 has type=voip it should return answer as MIXED, if obj1_type = obj2_type = voip it should return VOIP and similar for pstn for the same cid.


Hope I am clear with my question.










share|improve this question
























  • 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















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 obj1 has type=pstn and obj2 has type=voip it should return answer as MIXED, if obj1_type = obj2_type = voip it should return VOIP and similar for pstn for the same cid.


Hope I am clear with my question.










share|improve this question
























  • 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













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 obj1 has type=pstn and obj2 has type=voip it should return answer as MIXED, if obj1_type = obj2_type = voip it should return VOIP and similar for pstn for the same cid.


Hope I am clear with my question.










share|improve this question















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 obj1 has type=pstn and obj2 has type=voip it should return answer as MIXED, if obj1_type = obj2_type = voip it should return VOIP and similar for pstn for the same cid.


Hope I am clear with my question.







mongodb aggregation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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


















  • 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












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






share|improve this answer























  • 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











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















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

























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






share|improve this answer























  • 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















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






share|improve this answer























  • 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













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






share|improve this answer














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







share|improve this answer














share|improve this answer



share|improve this answer








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


















  • 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


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














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





















































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







Popular posts from this blog

Catalogne

Violoncelliste

Héron pourpré