# Bool query with whole and partial words matching

**URL:** <https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207>\
**Category:** Elasticsearch\
**Created:** [August 4, 2016, 10:57am UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207 "2016-08-04T10:57:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlp1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jlp1/32/6607_2.png) [@jlp1](https://discuss.elastic.co/u/jlp1)\
**Post date:** [August 4, 2016, 10:57am UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207/1 "2016-08-04T10:57:04Z")

</div>

I want to index contacts containing a first name and last name and be able to search against them by typing either whole word or just the beginning of word. The whole words should be rank higher.  
My mapping looks like this:

```
    PUT example
    {
      "settings": {
        "analysis": {
          "filter": {
            "edge_ngram_filter": {
              "type": "edge_ngram",
              "min_gram": 1,
              "max_gram": 50
            }
          },
          "analyzer": {
            "edge_ngram_analyzer": {
              "type": "custom",
              "tokenizer": "standard",
              "filter": [
                "lowercase",
                "edge_ngram_filter"
              ]
            }
          }
        }
      },
      "mappings": {
        "contact": {
          "properties": {
            "FirstName": {
              "type": "string",
              "analyzer": "edge_ngram_analyzer",
              "fields": {
                "raw": {
                  "type": "string",
                  "analyzer": "standard"
                }
              }
            },
            "LastName": {
              "type": "string",
              "analyzer": "edge_ngram_analyzer",
              "fields": {
                "raw": {
                  "type": "string",
                  "analyzer": "standard"
                }
              }
            }
          }
        }
      }
    }

```

And my query like this:

```
POST example/contact/_search
{
   "query": {
      "bool": {
         "should": [
            {
               "multi_match": {
                  "query": "kim w",
                  "fields": [
                     "*.raw"
                  ]
               }
            },
            {
               "multi_match": {
                  "type": "cross_fields",
                  "query": "kim w",
                  "fields": [
                     "FirstName",
                     "LastName"
                  ]
               }
            }
         ]
      }
   }
}

```

It does not work quite good because for a query "k w" it returns "kim west" and "william kennedy" which is ok.  
But for the query "kim w" it returns "krista porter" which is not good.  
So I need a query which, when two words are entered, must match both on them on two fields.

---

<div class="post-metadata">

**Author:** ![jlp1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jlp1/32/6607_2.png) [@jlp1](https://discuss.elastic.co/u/jlp1)\
**Post date:** [August 4, 2016, 12:37pm UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207/2 "2016-08-04T12:37:46Z")

</div>

[deleted because it did not work]

---

<div class="post-metadata">

**Author:** ![davidbkemp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/davidbkemp/32/594_2.png) [@davidbkemp](https://discuss.elastic.co/u/davidbkemp)\
**Post date:** [August 8, 2016, 8:03am UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207/3 "2016-08-08T08:03:34Z")

</div>

You need to specify a query analyser that is different to your index analyser. E.g a "standard" query analyser.

---

<div class="post-metadata">

**Author:** ![davidbkemp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/davidbkemp/32/594_2.png) [@davidbkemp](https://discuss.elastic.co/u/davidbkemp)\
**Post date:** [August 8, 2016, 8:34am UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207/4 "2016-08-08T08:34:06Z")

</div>

Sorry, the correct term is "search analyser":

[https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html)

You can specify the search analyser at index time (as described in the link above), or you can specify it at query time as described here:

[https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html#query-dsl-match-query-phrase](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html#query-dsl-match-query-phrase)

---

<div class="post-metadata">

**Author:** ![jlp1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jlp1/32/6607_2.png) [@jlp1](https://discuss.elastic.co/u/jlp1)\
**Post date:** [August 9, 2016, 7:38pm UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207/5 "2016-08-09T19:38:34Z")

</div>

Thanks for suggestion,  
here is my working solution:  
I changed should to must clause and used AND operator in edge-ngram part so every term in the query must match. I also use standard analyzer so the query Joh match John but not Jimmy.  
The raw fields part of the query is still in should clause so it increases full words score.

```
POST example/contact/_search
{
   "query": {
      "bool": {
         "must": [
            {
               "multi_match": {
                  "type": "cross_fields",
                  "query": "W Kim",
                  "fields": [
                     "FirstName",
                     "LastName"
                  ],
                  "operator": "and",
                  "analyzer": "standard"
               }
            }
         ],
         "should": [
            {
               "multi_match": {
                  "query": "W Kim",
                  "fields": [
                     "*.raw"
                  ],
                  "type": "cross_fields"
               }
            }
         ]
      }
   }
}
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 10:29pm UTC](https://discuss.elastic.co/t/bool-query-with-whole-and-partial-words-matching/57207/6 "2017-07-05T22:29:01Z")

</div>


