Skip to content

Instantly share code, notes, and snippets.

@clintongormley
Last active September 10, 2016 04:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clintongormley/7039568 to your computer and use it in GitHub Desktop.
Save clintongormley/7039568 to your computer and use it in GitHub Desktop.

First, setup the parent/child relationship

curl -XDELETE "http://localhost:9200/test"

curl -XPOST "http://localhost:9200/test" -d'
{
   "mappings": {
      "child": {
         "_parent": {
            "type": "parent"
         }
      },
      "parent": {}
   }
}'

then index some docs:

curl -XPOST "http://localhost:9200/test/_bulk" -d'
{ "index": { "_type": "parent", "_id": 1  }}
{ "title": "parent one"                    }
{ "index": { "_type": "parent", "_id": 2  }}
{ "title": "parent two"                    }
{ "index": { "_type": "child",  "_id": 3, "_parent": 1 }}
{ "title": "child of parent one", "foo": 1              }
{ "index": { "_type": "child",  "_id": 4, "_parent": 1 }}
{ "title": "child of parent one", "foo": 2              }
{ "index": { "_type": "child",  "_id": 5, "_parent": 1 }}
{ "title": "child of parent one", "foo": 3              }
{ "index": { "_type": "child",  "_id": 6, "_parent": 2 }}
{ "title": "child of parent two", "foo": 1              }
{ "index": { "_type": "child",  "_id": 7, "_parent": 2 }}
{ "title": "child of parent two", "foo": 2              }
'

Now we can search for parents that have at least cutoff children. Docs with too few children will have a negative score so we use min_score to exclude anything below zero.

curl -XPOST "http://localhost:9200/test/parent/_search" -d'
{
   "min_score": 0,
   "query": {
      "function_score": {
         "boost_mode": "mult",
         "functions": [
            {
               "script_score": {
                  "params": {
                     "cutoff": 3
                  },
                  "script": "_score < cutoff ? -1 : 1"
               }
            }
         ],
         "query": {
            "has_child": {
               "type": "child",
               "score_type": "sum",
               "query": {
                  "range": {
                     "foo": {
                        "gte": 1,
                        "lte": 3
                     }
                  }
               }
            }
         }
      }
   }
}'
Note
In 0.90.6, mult has changed to multiply

If we want to combine the cutoff with a full text query, then we can do so using a bool query:

curl -XPOST "http://localhost:9200/test/parent/_search" -d'
{
   "min_score": 0,
   "query": {
      "bool": {
         "must": [
            {
               "match": {
                  "title": "parent"
               }
            },
            {
               "function_score": {
                  "boost_mode": "mult",
                  "functions": [
                     {
                        "script_score": {
                           "params": {
                              "cutoff": 3
                           },
                           "script": "_score < cutoff ? -1 : 1"
                        }
                     }
                  ],
                  "query": {
                     "has_child": {
                        "type": "child",
                        "score_type": "sum",
                        "query": {
                           "range": {
                              "foo": {
                                 "gte": 1,
                                 "lte": 3
                              }
                           }
                        }
                     }
                  }
               }
            }
         ]
      }
   }
}'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment