Функция оценки скрипта не должна давать отрицательные оценки / Сбой запроса / Сбой всех сегментов для фазового запроса elasticsearch

#asp.net-core #elasticsearch

#asp.net-core #elasticsearch

Вопрос:

У меня есть asp.net core 3.1 web api, который индексирует документы в elasticsearch и запрашивает данные через поле ввода интерфейса. Это работает. Но через некоторое время, когда я пытаюсь выполнить поиск документов, которые уже были проиндексированы, скажем, 5 часов назад, это не дает мне никаких результатов и выдает следующие ошибки:

 - all shards failed for phase query elasticsearch
- `Caused by: java.lang.IllegalArgumentException: script score function must not produce negative scores, but got: [-1010.1054077148438]
org.elasticsearch.transport.RemoteTransportException: [CVSearcher-ElasticSearch][10.0.0.4:9300][indices:data/read/search[phase/query]]
Caused by: org.elasticsearch.search.query.QueryPhaseExecutionException: Query Failed [Failed to execute main query]
Caused by: java.lang.IllegalArgumentException: script score function must not produce negative scores, but got: [-2020.2108154296875]
org.elasticsearch.ElasticsearchException$1: script score function must not produce negative scores, but got: [-2020.2108154296875]
        at org.elasticsearch.ElasticsearchException.guessRootCauses(ElasticsearchException.java:644) ~[elasticsearch-7.6.0.jar:7.6.0]
        at org.elasticsearch.action.ActionListenerResponseHandler.handleException(ActionListenerResponseHandler.java:59) [elasticsearch-7.6.0.jar:7.6.0]
        at org.elasticsearch.action.search.SearchTransportService$ConnectionCountingHandler.handleException(SearchTransportService.java:423) [elasticsearch-7.6.0.jar:7.6.0]
        at org.elasticsearch.transport.TransportService$ContextRestoreResponseHandler.handleException(TransportService.java:1118) [elasticsearch-7.6.0.jar:7.6.0]
        at org.elasticsearch.transport.TransportService$DirectResponseChannel.processException(TransportService.java:1227) [elasticsearch-7.6.0.jar:7.6.0]
  

Почему это происходит?

Мои сценарии оценки выглядят следующим образом:

         public IEnumerable<Func<ScoreFunctionsDescriptor<ResumeDocument>, ScoreFunctionsDescriptor<ResumeDocument>>> ScoringScripts
    {
        get
        {
            //build a list of every scoring script.
            var scriptCollection = new List<Func<ScoreFunctionsDescriptor<ResumeDocument>, ScoreFunctionsDescriptor<ResumeDocument>>>();

            //add the location scoring function once geocoding is incorporated in the application
            //scriptCollection.Add(LocationScoringFunction);

            //Iterate over every technicalskill requirement in the filters, and add a corresponding script for this technical skill.
            foreach (var skill in _filters.TechnicalSkills)
            {
                scriptCollection.Add(sc => sc
                    .ScriptScore(fq => fq
                        //Add a filter so the script only applies to this specific technical skill
                        .Filter(fi => fi
                            .Term(t => t
                                .Field(ff => ff.TechnicalSkills.First().Id)
                                .Value(skill.TechnicalSkillId)
                            )
                        )
                        //Add the script itself. More details for building a scoring script can be found at https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-score-query.html
                        .Script(s => s
                        .Source("(doc['technicalSkills.yearsOfExperience'].value/params.minYears)   (doc['technicalSkills.interest'].value / 20)   (doc['technicalSkills.level'].value/20)")
                        .Params(p =>
                                p.Add("minYears", skill.MinYears   1)
                            )
                        )
                    )
                );
            }

            return scriptCollection;
        }
    }
  

Я добавил этот код, чтобы увидеть дополнительную информацию:

 var debugInformation = response.DebugInformation;
  

Результаты:

 "Valid NEST response built from a successful (200) low level call on POST: /resumes/_search?typed_keys=truen# Audit trail of this API call:n - [1] HealthyResponse: Node: http://elastic:9200/ Took: 00:00:01.0811937n# Request:n{}n# Response:n{"took":0,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"resumes","_type":"_doc","_id":"b10ca54d-e90f-428e-8edd-cca7f168bd27","_score":1.0,"_source":{"id":"b10ca54d-e90f-428e-8edd-cca7f168bd27","dateOfBirth":"2020-12-30T12:00:00.2240000Z","firstname":"Murat","surname":"Yilmaz","gender":"Man","nationality":"dasdfds","description":"wef","location":{"lat":0.0,"lon":0.0},"trainings":[],"languageSkills":[],"technicalSkills":[{"id":"8004b47f67a94ccf92e6054a","name":"React","interest":0,"level":0,"yearsOfExperience":-2019.8740588637916},{"id":"0133a6138f5d47a3a84df694","name":"Typescript","interest":0,"level":0,"yearsOfExperience":-2019.8740588637916},{"id":"e715dc3a4da34cd29a4adec0","name":"Javascript","interest":0,"level":0,"yearsOfExperience":-2019.8740588637916},{"id":"0c2a67d0f6e2431c81dc211f","name":"Programmeertalen","interest":1,"level":1,"yearsOfExperience":-2023.1211498973305},{"id":"5ecfbfd816e79f6308ffa522","name":"Technische skills","interest":1,"level":1,"yearsOfExperience":-2023.1211498973305},{"id":"03c972e8f0404eba9087d77a","name":"C#","interest":0,"level":0,"yearsOfExperience":-2.9158110882956882},{"id":"0c2a67d0f6e2431c81dc211f","name":"Programmeertalen","interest":1,"level":1,"yearsOfExperience":-2023.1211498973305},{"id":"5ecfbfd816e79f6308ffa522","name":"Technische skills","interest":1,"level":1,"yearsOfExperience":-2023.1211498973305},{"id":"8fd0bb8e1eb24ef697f7a191","name":"Java","interest":0,"level":0,"yearsOfExperience":-0.33127994524298426},{"id":"0c2a67d0f6e2431c81dc211f","name":"Programmeertalen","interest":1,"level":1,"yearsOfExperience":-2023.1211498973305},{"id":"5ecfbfd816e79f6308ffa522","name":"Technische skills","interest":1,"level":1,"yearsOfExperience":-2023.1211498973305}]}}]}}n"
  

Еще несколько журналов:

 [2020-11-05T01:30:00,000][INFO ][o.e.x.m.MlDailyMaintenanceService] [CVSearcher-ElasticSearch] triggering scheduled [ML] maintenance tasks
[2020-11-05T01:30:00,038][INFO][o.e.x.m.a.TransportDeleteExpiredDataAction] [CVSearcher-ElasticSearch] Deleting expired data
[2020-11-05T01:30:00,051][INFO ][o.e.x.s.SnapshotRetentionTask] [CVSearcher-ElasticSearch] starting SLM retention snapshot cleanup task
[2020-11-05T01:30:00,054][INFO ][o.e.x.m.a.TransportDeleteExpiredDataAction] [CVSearcher-ElasticSearch] Completed deletion of expired ML data
[2020-11-05T01:30:00,054][INFO ][o.e.x.m.MlDailyMaintenanceService] [CVSearcher-ElasticSearch] Successfully completed [ML] maintenance tasks
[2020-11-05T15:26:06,117][DEBUG][o.e.a.s.TransportSearchAction] [CVSearcher-ElasticSearch] [resumes][0], node[E1-wByZ3SkaTJ7BK0TvIoQ], [P], s[STARTED], a[id=hg3RohUHQx6UynW2I2ghmA]: Failed to execute [SearchRequest{searchType=QUERY_THEN_FETCH, indices=[resumes], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=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=128, allowPartialSearchResults=true, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"query":{"function_score":{"query":{"match_all":{"boost":1.0}},"functions":[{"filter":{"term":{"technicalSkills.id":{"value":"0c2a67d0f6e2431c81dc211f","boost":1.0}}},"script_score":{"script":{"source":"(doc['technicalSkills.yearsOfExperience'].value/params.minYears)   (doc['technicalSkills.interest'].value / 20)   (doc['technicalSkills.level'].value/20)","lang":"painless","params":{"minYears":1}}}}],"score_mode":"multiply","boost_mode":"sum","max_boost":3.4028235E38,"boost":1.0}}}}]
org.elasticsearch.transport.RemoteTransportException: [CVSearcher-ElasticSearch][10.0.0.4:9300][indices:data/read/search[phase/query]]
Caused by: org.elasticsearch.search.query.QueryPhaseExecutionException: Query Failed [Failed to execute main query]
        at org.elasticsearch.search.query.QueryPhase.executeInternal(QueryPhase.j
  

Комментарии:

1. Привет, не могли бы вы также добавить свой запрос к вопросу? особенно ваша оценка функции. Спасибо!

2. Привет, саиднасехи. Я включил код. Надеюсь, это достаточно понятно..

3. Единственный способ получить отрицательную оценку с помощью вашего скрипта — это если какой-либо документ содержит отрицательное значение для любого yearsOfExperience (маловероятно), interest (в конечном итоге), level (в конечном итоге). Может ли это быть так?

4. @Val Эти значения всегда положительные..

5. Что вы подразумеваете под «я не знаю, как просмотреть данные в elasticsearch»? Хороший способ отладки — распечатать запрос перед его отправкой. Как только у вас это будет, мы сможем упростить его отладку