How can I use ElasticSearch-Rails query dsl to return related relationships How can I use ElasticSearch-Rails query dsl to return related relationships elasticsearch elasticsearch

How can I use ElasticSearch-Rails query dsl to return related relationships


By default if you use dynamic mapping to load the data, then ES will create nested objects as flat objects and hence will loose the relation between the various nested properties. To maintain the proper relations we can use either nested objects or parent-child relations.

Now i will use nested objects to achieve the desired result:

Mapping:

PUT /index-3{  "mappings": {    "products":{      "properties": {        "id": {          "type": "long"        },        "name":{          "type": "string"        },        "family_id":{          "type": "long"        },        "collection_id":{          "type": "long"        },        "created_at":{          "type": "date"        },        "updated_at":{          "type": "date"        },        "benefits":{          "type": "nested",          "include_in_parent": true,          "properties": {            "id": {              "type": "long"            },            "name":{              "type":"string"            }          }        },        "categories":{          "type": "nested",          "include_in_parent": true,          "properties": {            "id":{              "type": "long"            },            "name":{              "type":"string"            }          }        }      }    }  }}

If you observe i have treated the children objects as nested mapping and included in the parent.

Now some sample data:

PUT /index-3/products/4{  "name":"product name 4",  "family_id":15,  "collection_id":6,  "created_at":"2015-04-13T12:49:42.000Z",  "updated_at":"2015-04-13T12:49:42.000Z",  "benefits":[    {"id":2,"name":"my benefit 2"},    {"id":6,"name":"my benefit 6"},    {"id":7,"name":"my benefit 7"}  ],  "categories":[    {"id":2,"name":"category 2"}  ]}PUT /index-3/products/5{  "name":"product name 5",  "family_id":16,  "collection_id":6,  "created_at":"2015-04-13T12:49:42.000Z",  "updated_at":"2015-04-13T12:49:42.000Z",  "benefits":[    {"id":5,"name":"my benefit 2"},    {"id":6,"name":"my benefit 6"},    {"id":7,"name":"my benefit 7"}  ],  "categories":[    {"id":3,"name":"category 2"}  ]}PUT /index-3/products/6{  "name":"product name 6",  "family_id":15,  "collection_id":5,  "created_at":"2015-04-13T12:49:42.000Z",  "updated_at":"2015-04-13T12:49:42.000Z",  "benefits":[    {"id":5,"name":"my benefit 2"},    {"id":55,"name":"my benefit 6"},    {"id":7,"name":"my benefit 7"}  ],  "categories":[    {"id":3,"name":"category 2"}  ]}

And now the query part:

GET index-3/products/_search{  "query": {    "filtered": {      "query": {        "match_all": {}      },      "filter": {        "terms": {          "benefits.id": [            5,6,7          ],          "execution": "and"        }      }    }  }}

Which produces the following result:

{   "took": 1,   "timed_out": false,   "_shards": {      "total": 1,      "successful": 1,      "failed": 0   },   "hits": {      "total": 1,      "max_score": 1,      "hits": [         {            "_index": "index-3",            "_type": "products",            "_id": "5",            "_score": 1,            "_source": {               "name": "product name 5",               "family_id": 16,               "collection_id": 6,               "created_at": "2015-04-13T12:49:42.000Z",               "updated_at": "2015-04-13T12:49:42.000Z",               "benefits": [                  {                     "id": 5,                     "name": "my benefit 2"                  },                  {                     "id": 6,                     "name": "my benefit 6"                  },                  {                     "id": 7,                     "name": "my benefit 7"                  }               ],               "categories": [                  {                     "id": 3,                     "name": "category 2"                  }               ]            }         }      ]   }}

At the time of query we have to use terms filter with "and execution" so it will retrieve only the documents with all the terms.