elastic / elasticsearch

Free and Open Source, Distributed, RESTful Search Engine
https://www.elastic.co/products/elasticsearch
Other
69.91k stars 24.73k forks source link

`suggest` searches against completion fields with a synonym set result in null pointer exceptions #114651

Open canada-j opened 1 week ago

canada-j commented 1 week ago

Elasticsearch Version

8.13.2

Installed Plugins

No response

Java Version

bundled

OS Version

Elastic Cloud

Problem Description

When performing a suggest search against a completion field whose search_analyzer contains a synonym_set, Elasticsearch returns a 500 response with a null pointer exception.

This behavior does not occur when using inline synonyms, or synonym_path, and the synonym_set behaves as expected when using the _analyze endpoint.

Expected: suggest searches on completion fields that utilize a synonym set return a non-error response, and the suggest prefix is correctly tokenized according to the rules of the synonym set.

Actual: a 500 response is returned, with a null_pointer_exception and a reason of Cannot invoke "org.elasticsearch.index.analysis.AnalyzerComponents.getCharFilters()" because "components" is null

Steps to Reproduce

Create a synonym set with an arbitrary number of synonyms ranging from 0 - n.

Create an index with the following details:

Create a document in this index with an arbitrary value for the previously created completion field

Make a request to the _search endpoint of the index using a suggest query with an arbitrary prefix

The following should produce a working example of the issue:

# Create synonym set
PUT _synonyms/test_synonyms
{
  "synonyms_set": [
    {
      "id": "test-1",
      "synonyms": "jerry, gary"
    }
  ]
}

# (Re)create index
DELETE test_synonym_index
PUT test_synonym_index
{
  "settings": {
    "analysis": {
      "filter": {
        "filter-synonym-completion": {
          "type": "synonym_graph",
          "updateable": "true",
          "synonyms_set": "test_synonyms"
        }
      },
      "analyzer": {
        "analyzer-completion-search": {
          "filter": [
            "lowercase",
            "filter-synonym-completion"
          ],
          "tokenizer": "standard"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "titleCompletion": {
        "type": "completion",
        "search_analyzer": "analyzer-completion-search"
      }
    }
  }
}

# Create a document
PUT test_synonym_index/_doc/1?refresh
{
  "titleCompletion" : {
    "input": "Gary is the title of this document"
  }
}

# Attempt a suggestion search
POST test_synonym_index/_search?filter_path=suggest
{
  "suggest": {
    "title": {
      "prefix": "jerry",
      "completion": {
        "field": "titleCompletion"
      }
    }
  }
}

It is worth noting that during index creation, if the synonym filter is created using in-line or synonyms_path, and updateable is omitted, the suggest search will work as expected:

# (Re)create index
DELETE test_synonym_index
PUT test_synonym_index
{
  "settings": {
    "analysis": {
      "filter": {
        "filter-synonym-completion": {
          "type": "synonym_graph",
          "synonyms": ["jerry, gary"]
        }
      },
      "analyzer": {
        "analyzer-completion-search": {
          "filter": [
            "lowercase",
            "filter-synonym-completion"
          ],
          "tokenizer": "standard"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "titleCompletion": {
        "type": "completion",
        "search_analyzer": "analyzer-completion-search"
      }
    }
  }
}

Logs (if relevant)

The exact error response from Elastic is as follows:

{
  "error": {
    "root_cause": [
      {
        "type": "null_pointer_exception",
        "reason": """Cannot invoke "org.elasticsearch.index.analysis.AnalyzerComponents.getCharFilters()" because "components" is null"""
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "test_synonym_index",
        "node": "RrPyixOFR-u3vsvSanASqg",
        "reason": {
          "type": "null_pointer_exception",
          "reason": """Cannot invoke "org.elasticsearch.index.analysis.AnalyzerComponents.getCharFilters()" because "components" is null"""
        }
      }
    ],
    "caused_by": {
      "type": "null_pointer_exception",
      "reason": """Cannot invoke "org.elasticsearch.index.analysis.AnalyzerComponents.getCharFilters()" because "components" is null""",
      "caused_by": {
        "type": "null_pointer_exception",
        "reason": """Cannot invoke "org.elasticsearch.index.analysis.AnalyzerComponents.getCharFilters()" because "components" is null"""
      }
    }
  },
  "status": 500
}
elasticsearchmachine commented 3 days ago

Pinging @elastic/es-search-relevance (Team:Search Relevance)