Как обновить устаревший запрос пользовательской оценки с помощью запроса функциональной оценки?

Я обновляюсь с elasticsearch 0.90.10 и NEST 0.12.0 до elasticsearch 1.3.4 и NEST 1.1.2 и пытаюсь заменить запрос пользовательской оценки, который устарел в версии 0.90.4, с запрос оценки функции.

Это мой старый код:

descriptor.Search<IndexedProduct>(s => s
    .Index(index)
    .From(((page ?? 1) - 1) * paging)
    .Size(paging)
    .Fields(f => f.ID, f => f.NumberOfSalesLastTwelveMonths, f => f.Description, f => f.itemIsInStock)
    .Query(qsc => qsc
        .CustomScore(sc => sc
            .Query(q => q
                .QueryString(qs => qs
                    .OnFieldsWithBoost(f => f
                        .Add(entry => entry.Description, 2.0)
                        .Add(entry => entry.LongDescription, 1.0)
                        .Add(entry => entry.ShortFamilyAndNumber, 4.0)
                        .Add(entry => entry.FamilyAndNumber, 4.0)
                        .Add(entry => entry.Suppliers, 1.5)
                        .Add(entry => entry.CleanSupplierReferences, 4.0)
                        .Add(entry => entry.SupplierReferences, 4.0)
                        .Add(entry => entry.SupplierBrands, 2.0)
                        .Add(entry => entry.Categories, 1.5)
                        .Add(entry => entry.ParameterValues, 1.0)
                        .Add(entry => entry.KeyWords, 2.0)
                        .Add(entry => entry.EANReferencesWMS, 4.0)
                    )
                    .Query(CleanUpText(EscapeSearchString(searchquery)))
                    .Operator(Operator.and)
                )
            )
            .Script("_score + ((_score > 0.99 ) ? doc['numberOfSalesLastTwelveMonths'].value : 0) + ((_score > 0.99 ) ? doc['itemIsInStock'].value : 0)")
        )
    ));

Это мой новый код:

descriptor.Search<IndexedProduct>(s => s
    .Index(index)
    .From(((page ?? 1) - 1) * paging)
    .Size(paging)
    .Fields(f => f.ID, f => f.NumberOfSalesLastTwelveMonths, f => f.Description, f => f.itemIsInStock)
    .Query(qsc => qsc
        .FunctionScore(fs => fs
            .Query(q => q
                .QueryString(qs => qs
                    .OnFieldsWithBoost(f => f
                        .Add(entry => entry.Description, 2.0)
                        .Add(entry => entry.LongDescription, 1.0)
                        .Add(entry => entry.ShortFamilyAndNumber, 4.0)
                        .Add(entry => entry.FamilyAndNumber, 4.0)
                        .Add(entry => entry.Suppliers, 1.5)
                        .Add(entry => entry.CleanSupplierReferences, 4.0)
                        .Add(entry => entry.SupplierReferences, 4.0)
                        .Add(entry => entry.SupplierBrands, 2.0)
                        .Add(entry => entry.Categories, 1.5)
                        .Add(entry => entry.ParameterValues, 1.0)
                        .Add(entry => entry.KeyWords, 2.0)
                        .Add(entry => entry.EANReferencesWMS, 4.0)
                    )
                    .Query(CleanUpText(EscapeSearchString(searchquery)))
                    .DefaultOperator(Operator.And)
                )
            )
            .ScriptScore(sc => sc
                .Script("_score + ((_score > 0.99 ) ? doc['numberOfSalesLastTwelveMonths'].value : 0) + ((_score > 0.99 ) ? doc['itemIsInStock'].value : 0)")
            )
        )
    )
);

Новый код завершается с SearchParseException, это запрос (из файла .log):

[{
    "from": 0,
    "size": 10,
    "fields": ["iD", "numberOfSalesLastTwelveMonths", "description", "itemIsInStock"],
    "query": {
        "function_score": {
            "query": {
                "query_string": {
                    "query": "*",
                    "fields": ["description^2", "longDescription^1", "shortFamilyAndNumber^4", "familyAndNumber^4", "suppliers^1.5", "cleanSupplierReferences^4", "supplierReferences^4", "supplierBrands^2", "categories^1.5", "parameterValues^1", "keyWords^2", "eANReferencesWMS^4"],
                    "default_operator": "and"
                }
            },
            "script_score": {
                "script": "_score + ((_score > 0.99 ) ? doc['numberOfSalesLastTwelveMonths'].value : 0) + ((_score > 0.99 ) ? doc['itemIsInStock'].value : 0)"
            }
        }
    }
}]

Полная запись в журнале:

[STARTED]: Failed to execute [org.elasticsearch.action.search.SearchRequest@7a87107e] lastShard [true]
org.elasticsearch.search.SearchParseException: [sta_products_public_nl_635490239970034081][0]: from[0],size[10]: Parse Failure [Failed to parse source [{"from":0,"size":10,"fields":["iD","numberOfSalesLastTwelveMonths","description","itemIsInStock"],"query":{"function_score":{"query":{"query_string":{"query":"*","fields":["description^2","longDescription^1","shortFamilyAndNumber^4","familyAndNumber^4","suppliers^1.5","cleanSupplierReferences^4","supplierReferences^4","supplierBrands^2","categories^1.5","parameterValues^1","keyWords^2","eANReferencesWMS^4"],"default_operator":"and"}},"script_score":{"script":"_score + ((_score > 0.99 ) ? doc['numberOfSalesLastTwelveMonths'].value : 0) + ((_score > 0.99 ) ? doc['itemIsInStock'].value : 0)"}}}}]]
        at org.elasticsearch.search.SearchService.parseSource(SearchService.java:660)
        at org.elasticsearch.search.SearchService.createContext(SearchService.java:516)
        at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:488)
        at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:257)
        at org.elasticsearch.search.action.SearchServiceTransportAction$5.call(SearchServiceTransportAction.java:206)
        at org.elasticsearch.search.action.SearchServiceTransportAction$5.call(SearchServiceTransportAction.java:203)
        at org.elasticsearch.search.action.SearchServiceTransportAction$23.run(SearchServiceTransportAction.java:517)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Caused by: org.elasticsearch.index.query.QueryParsingException: [sta_products_public_nl_635490239970034081] script_score the script could not be loaded
        at org.elasticsearch.index.query.functionscore.script.ScriptScoreFunctionParser.parse(ScriptScoreFunctionParser.java:97)
        at org.elasticsearch.index.query.functionscore.FunctionScoreQueryParser.parse(FunctionScoreQueryParser.java:128)
        at org.elasticsearch.index.query.QueryParseContext.parseInnerQuery(QueryParseContext.java:239)
        at org.elasticsearch.index.query.IndexQueryParserService.innerParse(IndexQueryParserService.java:342)
        at org.elasticsearch.index.query.IndexQueryParserService.parse(IndexQueryParserService.java:268)
        at org.elasticsearch.index.query.IndexQueryParserService.parse(IndexQueryParserService.java:263)
        at org.elasticsearch.search.query.QueryParseElement.parse(QueryParseElement.java:33)
        at org.elasticsearch.search.SearchService.parseSource(SearchService.java:644)
        ... 9 more
Caused by: org.elasticsearch.script.ScriptException: dynamic scripting for [mvel] disabled
        at org.elasticsearch.script.ScriptService.verifyDynamicScripting(ScriptService.java:374)
        at org.elasticsearch.script.ScriptService.compile(ScriptService.java:335)
        at org.elasticsearch.script.ScriptService.search(ScriptService.java:509)
        at org.elasticsearch.index.query.functionscore.script.ScriptScoreFunctionParser.parse(ScriptScoreFunctionParser.java:94)
        ... 16 more

Если я опускаю FunctionScore вот так, все работает нормально:

descriptor.Search<IndexedProduct>(s => s
    .Index(index)
    .From(((page ?? 1) - 1) * paging)
    .Size(paging)
    .Fields(f => f.ID, f => f.NumberOfSalesLastTwelveMonths, f => f.Description, f => f.itemIsInStock)
    .Query(q => q
        .QueryString(qs => qs
            .OnFieldsWithBoost(f => f
                .Add(entry => entry.Description, 2.0)
                .Add(entry => entry.LongDescription, 1.0)
                .Add(entry => entry.ShortFamilyAndNumber, 4.0)
                .Add(entry => entry.FamilyAndNumber, 4.0)
                .Add(entry => entry.Suppliers, 1.5)
                .Add(entry => entry.CleanSupplierReferences, 4.0)
                .Add(entry => entry.SupplierReferences, 4.0)
                .Add(entry => entry.SupplierBrands, 2.0)
                .Add(entry => entry.Categories, 1.5)
                .Add(entry => entry.ParameterValues, 1.0)
                .Add(entry => entry.KeyWords, 2.0)
                .Add(entry => entry.EANReferencesWMS, 4.0)
            )
            .Query(CleanUpText(EscapeSearchString(searchquery)))
            .DefaultOperator(Operator.And)
        )
    )

Это запрос (захваченный через Wireshark, я не смог настроить журнал/медленный журнал для регистрации всех запросов):

{
    "index": "sta_products_public_nl",
    "type": "indexedproduct"
}
{
    "from": 0,
    "size": 10,
    "fields": ["iD", "numberOfSalesLastTwelveMonths", "description", "itemIsInStock"],
    "query": {
        "query_string": {
            "query": "*",
            "fields": ["description^2", "longDescription^1", "shortFamilyAndNumber^4", "familyAndNumber^4", "suppliers^1.5", "cleanSupplierReferences^4", "supplierReferences^4", "supplierBrands^2", "categories^1.5", "parameterValues^1", "keyWords^2", "eANReferencesWMS^4"],
            "default_operator": "and"
        }
    }
}

Что я делаю не так?


person user247702    schedule 16.10.2014    source источник
comment
очень простой способ регистрировать все запросы во время разработки - использовать ipv4.fiddler вместо localhost во время работы скрипача.   -  person Martijn Laarman    schedule 16.10.2014
comment
Было бы полезно увидеть исключение java SearchParseException, возвращаемое в ответе на .Search().   -  person Martijn Laarman    schedule 16.10.2014
comment
@MartijnLaarman Я добавил полную запись в журнал.   -  person user247702    schedule 16.10.2014


Ответы (2)


Хорошо, большая подсказка здесь (должна была сразу щелкнуть со мной, если честно :))

Caused by: org.elasticsearch.script.ScriptException: dynamic scripting for [mvel] disabled

Раньше Elasticsearch включал сценарии по умолчанию, но, поскольку люди выставляли elasticsearch миру (эквивалентно открытию базы данных миру), их это немного утомляло.

Мы выпустили сообщение в блоге, в котором подробно описано, как вы можете повторно включить сценарии:

http://www.elasticsearch.org/blog/scripting/

person Martijn Laarman    schedule 16.10.2014
comment
И я должен был правильно прочитать всю запись в журнале, кажется :) script.disable_dynamic: false исправляет это, и, насколько я понимаю, я могу использовать field_value_factor, я обязательно посмотрю на это. - person user247702; 16.10.2014

Добавление

script.disable_dynamic: false 

не всегда решает проблему, у меня уже есть это в моем elasticsearch.yml, но я продолжаю получать вывод об ошибке:

Caused by: org.elasticsearch.script.ScriptException: dynamic scripting for [mvel] disabled
    at org.elasticsearch.script.ScriptService.verifyDynamicScripting(ScriptService.java:374)
    at org.elasticsearch.script.ScriptService.compile(ScriptService.java:335)
    at org.elasticsearch.script.ScriptService.search(ScriptService.java:509)
    at org.elasticsearch.index.query.functionscore.script.ScriptScoreFunctionParser.parse(ScriptScoreFunctionParser.java:94)
person Splifftor    schedule 19.10.2014