2013-08-21 4 views
5

Может ли кто-нибудь посоветовать мне, как сделать собственный подсчет в ElasticSearch при поиске массива ключевых слов из массива ключевых слов?ElasticSearch Custom Scoring with Arrays

Например, допустим есть массив ключевых слов в каждом документе, например, так:

{ // doc 1 
    keywords : [ 
      red : { 
        weight : 1 
       }, 
      green : { 
        weight : 2.0 
       }, 
      blue : { 
        weight: 3.0 
       }, 
      yellow : { 
        weight: 4.3 
       } 
     ] 
}, 
{ // doc 2 
    keywords : [ 
      red : { 
        weight : 1.9 
       }, 
      pink : { 
        weight : 7.2 
       }, 
      white : { 
        weight: 3.1 
       }, 
     ] 
}, 
... 

И я хочу, чтобы получить оценки для каждого из документов, на основе поиска, который соответствует ключевым словам против этого массива:

{ 
    keywords : [ 
      red : { 
        weight : 2.2 
       }, 
      blue : { 
        weight : 3.3 
       }, 
     ] 
} 

Но вместо того, чтобы просто определить, соответствуют ли они, я хочу использовать очень конкретный алгоритм подсчета очков:

enter image description here

Подсчет одного поля достаточно прост, но я не знаю, как управлять им с помощью массивов. Есть предположения?

+0

Hi @Aleksi Asikainen, вы нашли какое-либо решение этого (используя elasticsearch)? –

+0

Боюсь, что нет, но в настоящее время ElasticSearch имеет лучшую поддержку поддержки функций, что, я думаю, может быть достаточно хорошим для достижения этой цели: http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl- function-score-query.html –

ответ

1

А интересный вопрос! (И один, я думаю, мы сможем решить с некоторым сообщением)

Во-первых, посмотрели ли вы на пользовательский скрипт? Я уверен, вы можете это сделать медленно с этим. Если бы вы это сделали, я бы подумал о том, чтобы сделать rescore phase, где подсчет очков вычисляется только после того, как известно, что документ является хитом.

Однако Я думаю, вы можете сделать это с помощью оборудования elasticsearch. Поскольку я могу работать, вы делаете точечный продукт между документами (где весы фактически находятся на полпути между тем, что вы указываете, и 1).

Итак, мое первое предложение удаляет термин x/2n из вашего «пользовательского скоринга» (точечный продукт) и помещает ваши веса на полпути между 1 и пользовательским весом (например, 1.9 => 1.45).

... Прошу прощения, мне придется вернуться и изменить этот вопрос. Я думал об использовании вложенных документов с определенным уровнем повышения уровня, но, увы, параметр отображения _boost: only available for the root doc

p.s. Просто подумал, вы можете иметь поля с определенными уровнями повышения и хранить там условия, тогда вы можете сделать это легко, но вы потеряете точность. Затем был бы doc:

{ 
    "boost_1": ["aquamarine"], 
    "boost_2": null, //don't need to send this, just showing for clarity 
    ... 
    "boost_5": ["burgundy", "fuschia"] 
    ... 
} 

Тогда вы могли бы определить эти повышения в своем сопоставлении. Следует отметить, что значение повышения полей переносится в поле _all, поэтому теперь у вас будет сумка с взвешенными условиями в поле _all, тогда вы можете построить запрос bool: should с большим количеством запросов term с разным повышением (для веса второго документа).

Дайте мне знать, что вы думаете! Очень, очень интересный вопрос.

+0

Спасибо за длинный ответ. Я думаю, что вы правы, что оценка должна произойти с помощью фазы rescoring, если что-нибудь. К сожалению, имеется очень мало информации о том, как сделать спам с массивами, поэтому вопрос ...На данный момент я выбрал поиск с помощью ElasticSearch, а затем выполнил оценку результатов на PHP. Это очень расточительно, поэтому я предпочел бы полностью перевести процесс оценки в ElasticSearch. –