opensearch-project / OpenSearch

🔎 Open source distributed and RESTful search engine.
https://opensearch.org/docs/latest/opensearch/index/
Apache License 2.0
9.68k stars 1.79k forks source link

[BUG] Failed to create query: Index 0 out of bounds for length 0 #5379

Closed martin-gaievski closed 1 year ago

martin-gaievski commented 1 year ago

Describe the bug Getting 400 error with "type": "query_shard_exception", "reason": "failed to create query: Index 0 out of bounds for length 0" on search query.

Initially issue reported on ES 7.1, also reproducible on latest OpenSearch 2.4.0. Maybe a lucene bug https://github.com/apache/lucene/issues/11864 -> https://github.com/apache/lucene/issues/9763

I couldn't find exception in logs for 2.4.0, for ES7.1 following is in log:

Failed to execute [SearchRequest{searchType=QUERY_THEN_FETCH, indices=[sp_au], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, expand_wildcards_hidden=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false, ignore_throttled=true], types=[], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=null, allowPartialSearchResults=true, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"from":0,"size":36,"query":{"bool":{"must":[{"function_score":{"query":{"bool":{"should":[{"match":{"merchandising_keywords":{"query":"Gas Lift Storage Bed Frame with Ad Bed Head in King","operator":"OR","prefix_length":0,"max_expansions":50,"fuzzy_transpositions":true,"lenient":false,"zero_terms_query":"NONE","auto_generate_synonyms_phrase_query":true,"boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}},"functions":[],"score_mode":"multiply","boost_mode":"multiply","max_boost":3.4028235E38,"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}}}, cancelAfterTimeInterval=null}] lastShard [true]
RemoteTransportException[[7e35a45c91351a4aa5e5d7f369580842][__IP__][__PATH__[__PATH__]]]; nested: QueryShardException[failed to create query: Index 0 out of bounds for length 0]; nested: ArrayIndexOutOfBoundsException[Index 0 out of bounds for length 0];
Caused by: [__PATH__] QueryShardException[failed to create query: Index 0 out of bounds for length 0]; nested: ArrayIndexOutOfBoundsException[Index 0 out of bounds for length 0];

To Reproduce Steps to reproduce the behavior:

  1. Create a Index with the below setting and mapping.
    PUT test-index
    {
    "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "search_analyzer": {
            "filter": [
              "stop",
              "asciifolding",
              "elision",
              "lowercase",
              "synonym_graph",
              "snowball",
              "unique"
            ],
            "tokenizer": "standard",
            "type": "custom"
          },
          "index_analyzer": {
            "filter": [
              "stop",
              "asciifolding",
              "elision",
              "word_delimiter",
              "flatten_graph",
              "lowercase",
              "snowball",
              "unique"
            ],
            "tokenizer": "standard",
            "type": "custom"
          }
        },
        "filter": {
          "synonym_graph": {
            "lenient": "true",
            "synonyms": [
              "head board, bed head, bedhead, headboard"
            ],
            "type": "synonym_graph"
          },
          "synonyms": {
            "synonyms": [
              "head board, bed head, bedhead, headboard"
            ],
            "type": "synonym"
          },
          "word_delimiter": {
            "preserve_original": "true",
            "type": "word_delimiter"
          }
        }
      }
    }
    },
    "mappings": {
    "dynamic": "strict",
    "properties": {
      "merchandising_keywords": {
        "analyzer": "index_analyzer",
        "index_options": "docs",
        "search_analyzer": "search_analyzer",
        "type": "text"
      }
    }
    }
    }
dblock commented 1 year ago

Appreciate a unit test that reproduces this, maybe with a shorter query :)

martin-gaievski commented 1 year ago

Update mapping required to issue repro

msfroh commented 1 year ago

Adding back a search request that triggers the bug:

POST test-index/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "function_score": {
                        "query": {
                            "bool": {
                                "should": [
                                    {
                                        "match": {
                                            "merchandising_keywords": "Gas Lift Storage Bed Frame with Arched Bed Head in King"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                }
            ]
        }
    }
}

Since the exception is thrown within the MatchQueryBuilder, I suspect that we could repro with a simpler query like:

POST test-index/_search
{
    "query": {
         "match": {
           "merchandising_keywords": "Gas Lift Storage Bed Frame with Arched Bed Head in King"
         }
    }
}
msfroh commented 1 year ago

Here is a stack trace from a time when I was able to reproduce this:

QueryShardException[failed to create query: Index 0 out of bounds for length 0]; nested: ArrayIndexOutOfBoundsException[Index 0 out of bounds for length 0];
        at org.opensearch.index.query.QueryShardContext.toQuery(QueryShardContext.java:389)
        at org.opensearch.index.query.QueryShardContext.toQuery(QueryShardContext.java:372) 
        at org.opensearch.search.SearchService.parseSource(SearchService.java:889)
        at org.opensearch.search.SearchService.createContext(SearchService.java:726)
        at org.opensearch.search.SearchService.executeQueryPhase(SearchService.java:428)
        at org.opensearch.search.SearchService.access$500(SearchService.java:141)
        at org.opensearch.search.SearchService$2.lambda$onResponse$0(SearchService.java:401)
        at org.opensearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:58)
        at org.opensearch.action.ActionRunnable$2.doRun(ActionRunnable.java:73)
        at org.opensearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
        at org.opensearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:44)
        at org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:752)
        at org.opensearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
        at org.apache.lucene.util.QueryBuilder.newSynonymQuery(QueryBuilder.java:701)
        at org.opensearch.index.search.MatchQuery$MatchQueryBuilder.analyzeGraphBoolean(MatchQuery.java:749)
        at org.opensearch.index.search.MatchQuery$MatchQueryBuilder.createFieldQuery(MatchQuery.java:462)
        at org.opensearch.index.search.MatchQuery$MatchQueryBuilder.createQuery(MatchQuery.java:503)
        at org.opensearch.index.search.MatchQuery$MatchQueryBuilder.createFieldQuery(MatchQuery.java:383)
        at org.apache.lucene.util.QueryBuilder.createBooleanQuery(QueryBuilder.java:119)
        at org.opensearch.index.search.MatchQuery.parseInternal(MatchQuery.java:290)
        at org.opensearch.index.search.MatchQuery.parse(MatchQuery.java:282)
        at org.opensearch.index.query.MatchQueryBuilder.doToQuery(MatchQueryBuilder.java:426)
        at org.opensearch.index.query.AbstractQueryBuilder.toQuery(AbstractQueryBuilder.java:103)
        at org.opensearch.index.query.BoolQueryBuilder.addBooleanClauses(BoolQueryBuilder.java:324)
        at org.opensearch.index.query.BoolQueryBuilder.doToQuery(BoolQueryBuilder.java:310)
        at org.opensearch.index.query.AbstractQueryBuilder.toQuery(AbstractQueryBuilder.java:103)
        at org.opensearch.index.query.functionscore.FunctionScoreQueryBuilder.doToQuery(FunctionScoreQueryBuilder.java:308)
        at org.opensearch.index.query.AbstractQueryBuilder.toQuery(AbstractQueryBuilder.java:103)
        at org.opensearch.index.query.BoolQueryBuilder.addBooleanClauses(BoolQueryBuilder.java:324)
        at org.opensearch.index.query.BoolQueryBuilder.doToQuery(BoolQueryBuilder.java:308)
        at org.opensearch.index.query.AbstractQueryBuilder.toQuery(AbstractQueryBuilder.java:103)
        at org.opensearch.index.query.QueryShardContext.lambda$toQuery$3(QueryShardContext.java:373)
        at org.opensearch.index.query.QueryShardContext.toQuery(QueryShardContext.java:385)
        ... 15 more
mingshl commented 1 year ago

During reproducing the issue, this 404 error happens after creating index, then query with no document, it gets index out of bound error. if searching an index that not created, it returns "index_not_found_exception" as expected.

proposing solution to catch the error when constructing the synonym query. If the error is raised, should return no search result with status code 204, instead of 400 error (bad request). This is a valid request when querying no result.

elfisher commented 1 year ago

@martin-gaievski is this a feature or a bug fix? We typically don't label bug fixes to be highlighted on the roadmap. If it is a bug fix, please remove the "roadmap" label. Guidance on when to use the "roadmap" label can be found here.

Thanks!

martin-gaievski commented 1 year ago

it's a bug fix. Unfortunately I can't edit labels, it has been added by @macohen. @macohen, could you please help and remove "roadmap" label?

macohen commented 1 year ago

My mistake. Removed the label and (re)read the guidance. Thanks!

saratvemulapalli commented 1 year ago

@macohen @martin-gaievski this issue is labelled for 2.5, our code freeze is 1/10. Can you make it? If not lets bump it to 2.6.

macohen commented 1 year ago

We're waiting for some approvals on the PR. I think we can make it. We'll make the call be midday PST Monday. I'll remove the label then if we can't make it. Sound good?

dblock commented 1 year ago

Fixed in https://github.com/opensearch-project/OpenSearch/pull/5665 and https://github.com/opensearch-project/OpenSearch/pull/5758 (backport to 2.x).

mingshl commented 1 year ago

Fixed is also backport to 1.x #5912