How to fetch only the documents that have 3 different values in mongodb?











up vote
0
down vote

favorite












I have the following data in mongodb:



    {
"_id" : ObjectId("111"),
"id" : "111",
"classification" : [
{
"annotator" : "annotatorName1",
"category" : "white"
},
{
"annotator" : "annotatorName2",
"category" : "white"
},
{
"annotator" : "annotatorName3",
"category" : "black"
}
]
}

{
"_id" : ObjectId("222"),
"id" : "222",
"classification" : [
{
"annotator" : "annotatorName1",
"category" : "white"
},
{
"annotator" : "annotatorName2",
"category" : "blue"
},
{
"annotator" : "annotatorName3",
"category" : "black"
}
]
}

{
"_id" : ObjectId("333"),
"kind" : "youtube#video",
"etag" : "tagvalue",
"id" : "333"
}


Please note that the classification label does not exists in all my records, as shown in record with id: "333".



I need to get all the records from my database that have different category values.
So, I need a query that when I run it, I will only get the record that has the classification label, and has exactly 3 different category values, in this case, I want a query that will only return this to me:



{
"_id" : ObjectId("222"),
"id" : "222",
"classification" : [
{
"annotator" : "annotatorName1",
"category" : "white"
},
{
"annotator" : "annotatorName2",
"category" : "blue"
},
{
"annotator" : "annotatorName3",
"category" : "black"
}
]
}


What command should I enter in my terminal in order to get all the records that have 3 unique category values under classification, IFF classification exists?



Thank you for your help.










share|improve this question


























    up vote
    0
    down vote

    favorite












    I have the following data in mongodb:



        {
    "_id" : ObjectId("111"),
    "id" : "111",
    "classification" : [
    {
    "annotator" : "annotatorName1",
    "category" : "white"
    },
    {
    "annotator" : "annotatorName2",
    "category" : "white"
    },
    {
    "annotator" : "annotatorName3",
    "category" : "black"
    }
    ]
    }

    {
    "_id" : ObjectId("222"),
    "id" : "222",
    "classification" : [
    {
    "annotator" : "annotatorName1",
    "category" : "white"
    },
    {
    "annotator" : "annotatorName2",
    "category" : "blue"
    },
    {
    "annotator" : "annotatorName3",
    "category" : "black"
    }
    ]
    }

    {
    "_id" : ObjectId("333"),
    "kind" : "youtube#video",
    "etag" : "tagvalue",
    "id" : "333"
    }


    Please note that the classification label does not exists in all my records, as shown in record with id: "333".



    I need to get all the records from my database that have different category values.
    So, I need a query that when I run it, I will only get the record that has the classification label, and has exactly 3 different category values, in this case, I want a query that will only return this to me:



    {
    "_id" : ObjectId("222"),
    "id" : "222",
    "classification" : [
    {
    "annotator" : "annotatorName1",
    "category" : "white"
    },
    {
    "annotator" : "annotatorName2",
    "category" : "blue"
    },
    {
    "annotator" : "annotatorName3",
    "category" : "black"
    }
    ]
    }


    What command should I enter in my terminal in order to get all the records that have 3 unique category values under classification, IFF classification exists?



    Thank you for your help.










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have the following data in mongodb:



          {
      "_id" : ObjectId("111"),
      "id" : "111",
      "classification" : [
      {
      "annotator" : "annotatorName1",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName2",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName3",
      "category" : "black"
      }
      ]
      }

      {
      "_id" : ObjectId("222"),
      "id" : "222",
      "classification" : [
      {
      "annotator" : "annotatorName1",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName2",
      "category" : "blue"
      },
      {
      "annotator" : "annotatorName3",
      "category" : "black"
      }
      ]
      }

      {
      "_id" : ObjectId("333"),
      "kind" : "youtube#video",
      "etag" : "tagvalue",
      "id" : "333"
      }


      Please note that the classification label does not exists in all my records, as shown in record with id: "333".



      I need to get all the records from my database that have different category values.
      So, I need a query that when I run it, I will only get the record that has the classification label, and has exactly 3 different category values, in this case, I want a query that will only return this to me:



      {
      "_id" : ObjectId("222"),
      "id" : "222",
      "classification" : [
      {
      "annotator" : "annotatorName1",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName2",
      "category" : "blue"
      },
      {
      "annotator" : "annotatorName3",
      "category" : "black"
      }
      ]
      }


      What command should I enter in my terminal in order to get all the records that have 3 unique category values under classification, IFF classification exists?



      Thank you for your help.










      share|improve this question













      I have the following data in mongodb:



          {
      "_id" : ObjectId("111"),
      "id" : "111",
      "classification" : [
      {
      "annotator" : "annotatorName1",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName2",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName3",
      "category" : "black"
      }
      ]
      }

      {
      "_id" : ObjectId("222"),
      "id" : "222",
      "classification" : [
      {
      "annotator" : "annotatorName1",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName2",
      "category" : "blue"
      },
      {
      "annotator" : "annotatorName3",
      "category" : "black"
      }
      ]
      }

      {
      "_id" : ObjectId("333"),
      "kind" : "youtube#video",
      "etag" : "tagvalue",
      "id" : "333"
      }


      Please note that the classification label does not exists in all my records, as shown in record with id: "333".



      I need to get all the records from my database that have different category values.
      So, I need a query that when I run it, I will only get the record that has the classification label, and has exactly 3 different category values, in this case, I want a query that will only return this to me:



      {
      "_id" : ObjectId("222"),
      "id" : "222",
      "classification" : [
      {
      "annotator" : "annotatorName1",
      "category" : "white"
      },
      {
      "annotator" : "annotatorName2",
      "category" : "blue"
      },
      {
      "annotator" : "annotatorName3",
      "category" : "black"
      }
      ]
      }


      What command should I enter in my terminal in order to get all the records that have 3 unique category values under classification, IFF classification exists?



      Thank you for your help.







      mongodb mongodb-query






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 8 at 2:25









      circuito

      31




      31
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          The below aggregate can be used to find out the "id"s which have exactly 3 unique categories:



          db.collectionName.aggregate([
          {$match : {classification : {$exists : true}}},
          {$unwind: "$classification"},
          {$group: { _id: "$id", uniqueCategories: {$addToSet: "$classification.category"}}},
          {$project: {_id : 1, numberOfCategories: {$size: "$uniqueCategories"}} },
          {$match: {numberOfCategories: 3} }
          ])


          Explanation: We start with matching documents which have the classification element. Then we $unwind it so as to deconstruct the embedded array into separate documents. Then it is grouped by id, and using $addToSet the categories are collected into an array - this takes care of eliminating any dupes. Then we project its $size and match on 'equal to 3'.



          This aggregate will yield documents with the _id set to the id field of the documents in your collection that have 3 unique categories, which you can use to get to the documents. If your collection size is quite large, you should consider adding another $match stage in the beginning to restrict the dataset. As it stands now, it will be doing a collection scan.






          share|improve this answer





















          • WOW! This actually worked! Thank you!
            – circuito
            Nov 8 at 17:58










          • But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
            – circuito
            Nov 8 at 18:22










          • I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
            – Bajal
            Nov 8 at 19:10










          • I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
            – circuito
            Nov 10 at 0:33











          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%2f53200682%2fhow-to-fetch-only-the-documents-that-have-3-different-values-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
          0
          down vote



          accepted










          The below aggregate can be used to find out the "id"s which have exactly 3 unique categories:



          db.collectionName.aggregate([
          {$match : {classification : {$exists : true}}},
          {$unwind: "$classification"},
          {$group: { _id: "$id", uniqueCategories: {$addToSet: "$classification.category"}}},
          {$project: {_id : 1, numberOfCategories: {$size: "$uniqueCategories"}} },
          {$match: {numberOfCategories: 3} }
          ])


          Explanation: We start with matching documents which have the classification element. Then we $unwind it so as to deconstruct the embedded array into separate documents. Then it is grouped by id, and using $addToSet the categories are collected into an array - this takes care of eliminating any dupes. Then we project its $size and match on 'equal to 3'.



          This aggregate will yield documents with the _id set to the id field of the documents in your collection that have 3 unique categories, which you can use to get to the documents. If your collection size is quite large, you should consider adding another $match stage in the beginning to restrict the dataset. As it stands now, it will be doing a collection scan.






          share|improve this answer





















          • WOW! This actually worked! Thank you!
            – circuito
            Nov 8 at 17:58










          • But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
            – circuito
            Nov 8 at 18:22










          • I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
            – Bajal
            Nov 8 at 19:10










          • I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
            – circuito
            Nov 10 at 0:33















          up vote
          0
          down vote



          accepted










          The below aggregate can be used to find out the "id"s which have exactly 3 unique categories:



          db.collectionName.aggregate([
          {$match : {classification : {$exists : true}}},
          {$unwind: "$classification"},
          {$group: { _id: "$id", uniqueCategories: {$addToSet: "$classification.category"}}},
          {$project: {_id : 1, numberOfCategories: {$size: "$uniqueCategories"}} },
          {$match: {numberOfCategories: 3} }
          ])


          Explanation: We start with matching documents which have the classification element. Then we $unwind it so as to deconstruct the embedded array into separate documents. Then it is grouped by id, and using $addToSet the categories are collected into an array - this takes care of eliminating any dupes. Then we project its $size and match on 'equal to 3'.



          This aggregate will yield documents with the _id set to the id field of the documents in your collection that have 3 unique categories, which you can use to get to the documents. If your collection size is quite large, you should consider adding another $match stage in the beginning to restrict the dataset. As it stands now, it will be doing a collection scan.






          share|improve this answer





















          • WOW! This actually worked! Thank you!
            – circuito
            Nov 8 at 17:58










          • But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
            – circuito
            Nov 8 at 18:22










          • I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
            – Bajal
            Nov 8 at 19:10










          • I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
            – circuito
            Nov 10 at 0:33













          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          The below aggregate can be used to find out the "id"s which have exactly 3 unique categories:



          db.collectionName.aggregate([
          {$match : {classification : {$exists : true}}},
          {$unwind: "$classification"},
          {$group: { _id: "$id", uniqueCategories: {$addToSet: "$classification.category"}}},
          {$project: {_id : 1, numberOfCategories: {$size: "$uniqueCategories"}} },
          {$match: {numberOfCategories: 3} }
          ])


          Explanation: We start with matching documents which have the classification element. Then we $unwind it so as to deconstruct the embedded array into separate documents. Then it is grouped by id, and using $addToSet the categories are collected into an array - this takes care of eliminating any dupes. Then we project its $size and match on 'equal to 3'.



          This aggregate will yield documents with the _id set to the id field of the documents in your collection that have 3 unique categories, which you can use to get to the documents. If your collection size is quite large, you should consider adding another $match stage in the beginning to restrict the dataset. As it stands now, it will be doing a collection scan.






          share|improve this answer












          The below aggregate can be used to find out the "id"s which have exactly 3 unique categories:



          db.collectionName.aggregate([
          {$match : {classification : {$exists : true}}},
          {$unwind: "$classification"},
          {$group: { _id: "$id", uniqueCategories: {$addToSet: "$classification.category"}}},
          {$project: {_id : 1, numberOfCategories: {$size: "$uniqueCategories"}} },
          {$match: {numberOfCategories: 3} }
          ])


          Explanation: We start with matching documents which have the classification element. Then we $unwind it so as to deconstruct the embedded array into separate documents. Then it is grouped by id, and using $addToSet the categories are collected into an array - this takes care of eliminating any dupes. Then we project its $size and match on 'equal to 3'.



          This aggregate will yield documents with the _id set to the id field of the documents in your collection that have 3 unique categories, which you can use to get to the documents. If your collection size is quite large, you should consider adding another $match stage in the beginning to restrict the dataset. As it stands now, it will be doing a collection scan.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 8 at 3:23









          Bajal

          1,98411018




          1,98411018












          • WOW! This actually worked! Thank you!
            – circuito
            Nov 8 at 17:58










          • But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
            – circuito
            Nov 8 at 18:22










          • I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
            – Bajal
            Nov 8 at 19:10










          • I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
            – circuito
            Nov 10 at 0:33


















          • WOW! This actually worked! Thank you!
            – circuito
            Nov 8 at 17:58










          • But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
            – circuito
            Nov 8 at 18:22










          • I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
            – Bajal
            Nov 8 at 19:10










          • I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
            – circuito
            Nov 10 at 0:33
















          WOW! This actually worked! Thank you!
          – circuito
          Nov 8 at 17:58




          WOW! This actually worked! Thank you!
          – circuito
          Nov 8 at 17:58












          But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
          – circuito
          Nov 8 at 18:22




          But Bajal, it always fetches only 50.. I know there are more than 50. I want it to retrieve all of them with different classification categories. Why is it only fetching 50?
          – circuito
          Nov 8 at 18:22












          I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
          – Bajal
          Nov 8 at 19:10




          I am guessing you are using robo-3t? It is a limitation of that tool: See: github.com/Studio3T/robomongo/issues/1157 You can run this on the shell and iterate. Or if you execute from any code you will get full results. Don't forget to accept/upvote if this helped :)
          – Bajal
          Nov 8 at 19:10












          I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
          – circuito
          Nov 10 at 0:33




          I accepted it but it won't let me upvote since I don't have much reputation. Thank you very much for your answer. This solved my problem! :)
          – circuito
          Nov 10 at 0:33


















          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%2f53200682%2fhow-to-fetch-only-the-documents-that-have-3-different-values-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







          這個網誌中的熱門文章

          Academy of Television Arts & Sciences

          L'Équipe

          1995 France bombings