# Querying Arrays and Objects

We can perform matching queries for objects, elements in objects, arrays, and elements in arrays. We can even perform matching queries on nested object and array fields. Now, we will learn about matching starting with normal matching.

# Normal matching

Each <key, value> in an incoming parameter constructs a filter condition. When there are multiple <key, value> pairs, all the conditions must be satisfied, and the relationship among them is "and". For an or relationship, you can use [command.or]((reference-client-api/database/command.or)).

For example, to find out unfinished to-dos whose progress is 50:

db.collection('todos').where({
  done: false,
  progress: 50
}).get()

# Match nested fields in records

Assume a collection contains the following record:

{
  "style": {
    "color": "red"
  }
}

If we want to find the records with a style.color of red in the collection, we can pass an object with the same structure to implement query conditions or use a "dot notation" query:

// Method 1
db.collection('todos').where({
  style: {
    color: 'red'
  }
}).get()

// Method 2
db.collection('todos').where({
  'style.color': 'red'
}).get()

# Match arrays, elements in arrays, the nth element in arrays, and match by using query commands

Match arrays

Assume a collection contains the following record:

{
  "numbers": [10, 20, 30]
}

We can pass a completely identical array to filter this record:

db.collection('todos').where({
  numbers: [10, 20, 30]
}).get()

Match elements in arrays

To find records whose array values in the array field contain a given value, we can pass the value to match when matching array fields. For the example above, we can pass an element in the array to filter all records with a 20 in the numbers field value:

db.collection('todos').where({
  numbers: 20
}).get()

Match the nth element in arrays

To find records whose nth array element in the array field is a given value, we can set field.subscript to key and set the target value to value in <key, value> matching. For the example above, if we want to find records whose second value in the number field is 20, we can perform the following query (note: the array subscript starts from 0):

db.collection('todos').where({
  'numbers.1': 20
}).get()

Match using query commands

When matching array fields, you can also use commands, such as lt and gt, to filter the records in the field array that satisfy the given comparison criteria. For the example above, we can find all the records with a value greater than 25 in the array value of the numbers field:

const _ = db.command
db.collection('todos').where({
  numbers: _.gt(25)
}).get()

A Query command can also be used in combination with a logic command. For example, to find records with a value greater than 25 and a value less than 15 in the array of the numbers field:

const _ = db.command
db.collection('todos').where({
  numbers: _.gt(25).and(_.lt(15))
}).get()

# Match multiple nested arrays and objects

All of the rules above can be nested. Assume a collection contains the following record:

{
  "root": {
    "objects": [
      {
        "numbers": [10, 20, 30]
      },
      {
        "numbers": [50, 60, 70]
      }
    ]
  }
}

As shown below, we can find all the records in a collection whose third value of the second numbers field of the root.objects field array is equal to 70:

db.collection('todos').where({
  'root.objects.1.numbers.2': 70
}).get()

Note that it is not necessary to specify the subscript. For example, we can find all the records in a collection with any numbers field of the root.objects field array that contains 30:

db.collection('todos').where({
  'root.objects.numbers': 30
}).get()