Search code examples
elasticsearch

how to filter by field in fuzzy elastic search query


I can fuzzy search in elastic by company name in the following way:

curl -XGET http://localhost:9200/companies_test/_search -H 'Content-Type: application/json' -d '{
       "query": {
          "bool": {
            "must": {
              "match": {
                "name": {
                  "query": "openAI",
                  "fuzziness": "AUTO"
                }
              }
            }
          }
        }
      }
  }'

it returns

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "companies_test",
        "_type": "_doc",
        "_id": "0",
        "_score": 0.2876821,
        "_source": {
          "regionName": "North America",
          "name": "OpenAI",
          "id": "0"
        }
      }
    ]
  }
}

But when I try to add regionName filter to it:

 curl -XGET http://localhost:9200/companies_test/_search -H 'Content-Type: application/json' -d '{
       "query": {
          "bool": {
            "must": {
              "match": {
                "name": {
                  "query": "openai",
                  "fuzziness": "AUTO"
                }
              }
            },
            "filter": {
              "term": {
                "regionName": "North America"
              }
            }
          }
        }
      }
  }'

it returns 0 results:

{
  "took": 38,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

How to fix my elastic search query to fuzzy search by company name in specific regionName?

Update

here is my document structure:

curl -XGET http://localhost:9200/companies_test/_mapping -H 'Content-Type: application/json'

returns:

{
  "companies_test": {
    "mappings": {
      "_doc": {
        "properties": {
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "regionName": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

Also I tried to search and filter by lowered case text but it gives no result as well.

curl -XGET http://localhost:9200/companies_test/_search -H 'Content-Type: application/json' -d '{
       "query": {
          "bool": {
            "must": {
              "match": {
                "name": {
                  "query": "open ai",
                  "fuzziness": "AUTO"
                }
              }
            },
            "filter": {
              "term": {
                "regionName": "north america"
              }
            }
          }
        }
      }
  }'

returns

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

Solution

  • Thanks for a mapping

    There are two ways to transform your filter

    I. Using the term query, a keyword multifield and an original text

          "term": {
            "regionName.keyword": "North America"
          }
    

    II. Using the match query, a text multifield and a lowercased text

          "match": {
            "regionName": "north america"
          }