2

I am trying to construct a Mongodb query to return a field value. My JSON looks like this:

"question" : "Global_Deployment",
                    "displayOrder" : 1,
                    "answerOptions" : {
                        "fieldId" : "1001",
                        "fieldType" : "radiobutton",
                        "fieldName" : "Global Deployment?",
                        "fieldLabel" : "Global Deployment?",
                        "helpText" : "Help will go here",
                        "emailTagFormControl" : "Global_Deployment?",
                        "source" : "custom",
                        "status" : "active",
                        "required" : "true",
                        "multiSelect" : "false",
                        "purgeFlag" : "false",
                        "enableAuditTrack" : "false",
                        "fields" : [],
                        "fieldValue" : "Yes",
                        "options" : [ 
                            {
                                "optionName" : "Yes"
                            }, 
                            {
                                "optionName" : "No"
                            }
                        ],
                        "comments" : {
                            "commentId" : "C1001",
                            "commentDetails" : []
                        }

My query to reach the field with the fieldName "Global Deployment" is this:

db.getCollection('requests').find({"sections.questions.answerOptions.fieldName":"Global Deployment?"})

What I want to know is what to add to this query to return the value of "fieldValue", which is on a different line in the JSON. I am new to Mongodb. Any help would be greatly appreciated.

4 Answers 4

2

1) If you've multiple documents in DB with "fieldName" : "Global Deployment?", then .find() would return all the matching documents i.e; in the output what you get is an array of documents then you need to iterate through the array to get answerOptions.fieldValue for each document, Check the below scenario, as I've explained there are chances of getting multiple documents if "sections.questions.answerOptions.fieldName" is not an unique field.

db.getCollection('requests').find({"sections.questions.answerOptions.fieldName":"Global Deployment?"}, {'sections.questions.answerOptions.fieldValue':1})

Output of find :

/* 1 */
[{
    "_id" : ObjectId("5d4e19826e173840500f5674"),
    "answerOptions" : {
        "fieldValue" : "Yes"
    }
},
/* 2 */
{
    "_id" : ObjectId("5d4e19826e073840500f5674"),
    "answerOptions" : {}
}]

If you only need documents which has fieldValue in it then do this :

db.getCollection('requests').find({"sections.questions.answerOptions.fieldName":"Global Deployment?", 'sections.questions.answerOptions.fieldValue':{$exists: true}}, {'answerOptions.fieldValue':1})

Ok now you've array of documents then do iterate thru each to retrieve your value, check this mongoDB cursor tutorial .

2) If you think fieldName is unique across collection, then you can use .findOne() , which would exactly return one document (In case if you've multiple matching documents it would return first found doc) :

db.getCollection('requests').findOne({"sections.questions.answerOptions.fieldName":"Global Deployment?"}, {'sections.questions.answerOptions.fieldValue':1})

Output of findOne :

{
    "_id" : ObjectId("5d4e19826e173840500f5674"),
    "answerOptions" : {
        "fieldValue" : "Yes"
    }
}

If you see .find({},{}) has two arguments, second one is called projection which literally be useful if you want to retrieve only required fields in the response, By default mongoDB will return the entire document what ever you've posted in the question will be retrieved, Data in mongoDB flows as JSON's so operating will be similar to using JSON's, Here you can retrieve the required fields out of result, but for best use of network efficiency if you don't need entire document you'll only get the required fields using projection.

Sign up to request clarification or add additional context in comments.

Comments

0

You can specify the second condition separated by comma. Either you are trying to filter data with $and or with $or

With simple approach:

{"sections.questions.answerOptions.fieldName":"Global Deployment?","sections.questions.answerOptions.fieldValue":"Yes" }

By using $and method:

.find(
     {
      $and: [
            {"sections.questions.answerOptions.fieldName":"Global Deployment?"},
            {"sections.questions.answerOptions.fieldValue":"Yes"}
            ]
     }
    )

Same way you can use $or method. Just replace $and with $or.

Edit: If you want to retrieve specific value (in your case fieldValue), query would be:

db.getCollection('requests').find({
"sections.questions.answerOptions.fieldName":"Global Deployment?"
}).map(function(item){
return item.fieldValue
}) 

8 Comments

Thank you for answering. How do I retrieve the field value? I won't always know what it is.
Can you please specify your expected output from the JSON you mentioned?
I would like the query to return "Yes" in this case, which is the fieldValue of fieldName "Global Deployment"
You want to retrieve the value within MongoDb query? if this is what you want you can query like db.getCollection('requests').find(filter query as i mentioned in my answer).forEach(function(item){ item.fieldValue})
And i think you only needs to retrieve value based on fieldName. In this case you don't need any $or , $and method
|
0

The correct answer here is the method .distinct() (docs)

In your case try it like this:

db.getCollection('requests').find({"sections.questions.answerOptions.fieldName":"Global Deployment?"}).distinct('fieldValue');

That will return only the value you want.

Comments

0

If you use findOne you can use dot notation. For example, if we start with creating a collection to test using the following to get close to your sample:

    db.stackOverflow.insertOne({
  sections: {
    questions: {
      question: "Global_Deployment",
      displayOrder: 1,
      answerOptions: {
        fieldId: "1001",
        fieldType: "radiobutton",
        fieldName: "Global Deployment?",
        fieldLabel: "Global Deployment?",
        helpText: "Help will go here",
        emailTagFormControl: "Global_Deployment?",
        source: "custom",
        status: "active",
        required: "true",
        multiSelect: "false",
        purgeFlag: "false",
        enableAuditTrack: "false",
        fields: [],
        fieldValue: "Yes",
        options: [
          {
            optionName: "Yes",
          },
          {
            optionName: "No",
          },
        ],
        comments: {
          commentId: "C1001",
          commentDetails: [],
        },
      },
    },
  },
})

then, this query will return "Yes".

db.stackOverflow.findOne({}).sections.questions.answerOptions.fieldValue

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.