3

I have mongodb document structure like below:

{
"_id" : ObjectId("5b58673721b4b95a193d4e91"),
"pageId" : "page1",
"fields" : [ 
    {
        "fieldId" : "Field1",
        "value" : "test"
    }, 
    {
        "fieldId" : "Field2",
        "value" : 6.0
    },
    {
        "fieldId" : "Field3",
        "value" : 8.0
    }
]}

}

I want to find all the documents in the collection where the value for the object having fieldId as 'Field2' is greater than value for the object having fieldId as 'Field3'.

i.e. Field2(value) > Field3(value)

The number of objects in fields array is not fixed. I can not compare by position. I have to match objects by field Id. So, in this case, it would have to be on the lines of:
Compare: object value where fieldId='Field2' with object value where fieldId='Field3'

How do I write MongoDB query for this?

I am using MongoDB version 4.0
(There might be instances where fields may not be present in documents. e.g. documents created before these fields are introduced in the design)

4
  • Would you like to only include documents for comparison when both fields are present ? Commented Feb 4, 2019 at 14:41
  • That will do. But if there is a way to include documents without those fields using some default value. I would like to know that too. Commented Feb 4, 2019 at 14:52
  • Sure. What are the default values ? Commented Feb 4, 2019 at 14:53
  • Let's assume it would be 10 and 5 for these two fields. Commented Feb 4, 2019 at 15:20

1 Answer 1

2

Assuming you always have two fields in document you can use below query in 3.6.

Locate the field doc using indexofarray with fieldId as search criteria followed by value comparison.

db.collectionname.find(
{"$expr":{
  "$let":{
    "vars":{
      "field2":{"$arrayElemAt":["$fields",{"$indexOfArray":["$fields.fieldId","Field2"]}]},
      "field3":{"$arrayElemAt":["$fields",{"$indexOfArray":["$fields.fieldId","Field3"]}]}
    },
    "in":{"$gt":["$$field2.value","$$field3.value"]}}
}})
Sign up to request clarification or add additional context in comments.

3 Comments

Aren't all the field entries at array index 0?
@DaveStSomeWhere Not sure I follow. The field entries are at different position in different documents. So $indexofarray to search the index of field entry by field id followed by $arrayElemAt to retrieve the field entry at that index.
Ok - was testing and this didn't work until your most recent update, glad it works now - so ignore my confusion.

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.