Aggregation and Condition in Mongodb












1














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
    Nov 21 '18 at 13:34
















1














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
    Nov 21 '18 at 13:34














1












1








1







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 Nov 21 '18 at 17:39









mickl

11.6k51535




11.6k51535










asked Nov 21 '18 at 13:34









Aniket Maithani

8010




8010












  • This is what I have tried so far : db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }] . But unable to build query ahead.
    – Aniket Maithani
    Nov 21 '18 at 13:34


















  • This is what I have tried so far : db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }] . But unable to build query ahead.
    – Aniket Maithani
    Nov 21 '18 at 13:34
















This is what I have tried so far : db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }] . But unable to build query ahead.
– Aniket Maithani
Nov 21 '18 at 13:34




This is what I have tried so far : db.CallLeg.aggregate([ {$match: {cid: "ABCDEFGH"}, }] . But unable to build query ahead.
– Aniket Maithani
Nov 21 '18 at 13:34












1 Answer
1






active

oldest

votes


















1














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
    Nov 22 '18 at 8:27












  • @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
    Nov 22 '18 at 8:29












  • 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
    Nov 22 '18 at 8:32












  • Any chance to upgrade to 3.4 ?
    – mickl
    Nov 22 '18 at 8:36










  • I have upgraded it to 3.4 ? Should I try your answer now ?
    – Aniket Maithani
    Nov 22 '18 at 8:41











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',
autoActivateHeartbeat: false,
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









1














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
    Nov 22 '18 at 8:27












  • @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
    Nov 22 '18 at 8:29












  • 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
    Nov 22 '18 at 8:32












  • Any chance to upgrade to 3.4 ?
    – mickl
    Nov 22 '18 at 8:36










  • I have upgraded it to 3.4 ? Should I try your answer now ?
    – Aniket Maithani
    Nov 22 '18 at 8:41
















1














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
    Nov 22 '18 at 8:27












  • @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
    Nov 22 '18 at 8:29












  • 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
    Nov 22 '18 at 8:32












  • Any chance to upgrade to 3.4 ?
    – mickl
    Nov 22 '18 at 8:36










  • I have upgraded it to 3.4 ? Should I try your answer now ?
    – Aniket Maithani
    Nov 22 '18 at 8:41














1












1








1






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 Nov 22 '18 at 8:29

























answered Nov 21 '18 at 17:39









mickl

11.6k51535




11.6k51535












  • mickl, while trying your query I get the following response : "errmsg" : "bad query: BadValue: unknown top level operator: $expr",
    – Aniket Maithani
    Nov 22 '18 at 8:27












  • @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
    Nov 22 '18 at 8:29












  • 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
    Nov 22 '18 at 8:32












  • Any chance to upgrade to 3.4 ?
    – mickl
    Nov 22 '18 at 8:36










  • I have upgraded it to 3.4 ? Should I try your answer now ?
    – Aniket Maithani
    Nov 22 '18 at 8:41


















  • mickl, while trying your query I get the following response : "errmsg" : "bad query: BadValue: unknown top level operator: $expr",
    – Aniket Maithani
    Nov 22 '18 at 8:27












  • @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
    Nov 22 '18 at 8:29












  • 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
    Nov 22 '18 at 8:32












  • Any chance to upgrade to 3.4 ?
    – mickl
    Nov 22 '18 at 8:36










  • I have upgraded it to 3.4 ? Should I try your answer now ?
    – Aniket Maithani
    Nov 22 '18 at 8:41
















mickl, while trying your query I get the following response : "errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
Nov 22 '18 at 8:27






mickl, while trying your query I get the following response : "errmsg" : "bad query: BadValue: unknown top level operator: $expr",
– Aniket Maithani
Nov 22 '18 at 8:27














@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
Nov 22 '18 at 8:29






@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
Nov 22 '18 at 8:29














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
Nov 22 '18 at 8:32






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
Nov 22 '18 at 8:32














Any chance to upgrade to 3.4 ?
– mickl
Nov 22 '18 at 8:36




Any chance to upgrade to 3.4 ?
– mickl
Nov 22 '18 at 8:36












I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
Nov 22 '18 at 8:41




I have upgraded it to 3.4 ? Should I try your answer now ?
– Aniket Maithani
Nov 22 '18 at 8:41


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




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

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'