1
votes

Let's say I have users indexed with documents such as these:

{
    "name": "Fred Jonsson",
    "age": 24,
    "emails": [
        {
            "active": false,
            "address": "[email protected]",
        },
        {
            "active": false,
            "address": "[email protected]",
        },
        {
            "active": true,
            "address": "[email protected]",
        },
        {
            "active": false,
            "address": "[email protected]",
        },
   }
}

Does the ElasticSearch DSL allow me to construct a query where I could search for people by their e-mail address, but only if the address is active? In more abstract terms, search documents by nested objects conditioned on other properties of those objects.

A search fulfilling this criterion would return this document for a search for "[email protected]" or "engineeringcorp.com", but would not return this document when searching for "[email protected]".

2

2 Answers

1
votes

Yes, you just need to initiate a nested query on your documents. In your mappings, you need to set "emails" as "type":"nested". This will create "hidden" documents of every object in your array that are associated with this parent document.

{
   "query": {
      "nested": {
         "path": "emails",
         "query": {
            "bool": {
               "must": [
                  {
                     "term": {
                        "active": {
                           "value": "true"
                        }
                     }
                  },
                  {
                     "match": {
                        "address": "[email protected]"
                     }
                  }
               ]
            }
         }
      }
   }
}
1
votes

For example, if you want to search for email: [email protected] which is active, you would do this:

{
  query: {
    nested: {
      path: 'emails',
      query: {
        bool: {
          must: [
            {
              term: {
                'emails.active': true
              }
            },
            {
              term: {
                'emails.address': "[email protected]"
              }
            }
          ]
        }
      }
    }
  }
}