Rails elasticsearch _geo_distance и пользовательская оценка/сортировка

Таким образом, мое приложение Rails, использующее elasticsearch (с searchkick), отлично работает с использованием функции упорядочивания _geo_distance, однако мне нужно выполнить более сложное упорядочивание, включающее местоположение И попытку продвигать точное совпадение строки имени компании.

Например, если я делаю запрос и есть 10 возвращаемых результатов по восходящему расстоянию, но результат № 5 также является точным совпадением строки с названием компании в записи, я хотел бы повысить/поднять его до позиции № 1 ( в основном отменяет сортировку по расстоянию для этой записи).

Я вижу два способа решить эту проблему, но у меня возникают проблемы с обоими.

Во-первых, нужно было бы сделать это на начальном запросе, чтобы elasticsearch справился с работой.

Во-вторых, будет выполняться повторная сортировка результатов, возвращаемых elasticsearch, для поиска точного совпадения и изменения порядка, если это необходимо.

Проблема с первым методом заключается в том, что встроенные механизмы подсчета очков полностью переключаются на расстояние при вызове _geo_distance, что заставляет меня задаться вопросом, как смешивать пользовательские функции подсчета очков с местоположением.

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

Есть ли способ сделать что-то до или после запроса, чтобы продвигать документ в результатах таким образом?

Спасибо.


person kayatela    schedule 31.08.2014    source источник


Ответы (1)


На самом деле, есть много способов «управлять» подсчетом очков. Перед индексированием, если у вас уже есть какой-то документ, он должен получить высокий балл/повышение. Вы можете поставить высокую оценку специальному документу перед индексированием, см. здесь.

Если вы не можете определить повышение до индексации, вы можете повысить его в команде запроса. Что касается повышающего запроса, есть также много вариантов, и это зависит от того, какой запрос вы использовали.

Для запроса строки запроса:

Вы можете усилить некоторые поля, такие как fields" : ["content", "name.*^5"], или повысить некоторую команду запроса, например, quick^2 fox (это может сработать для вас, просто дополнительно увеличьте имя).

Для других:

Вы можете усилить запрос термина, например, повысить случай «ivan»:

"term" : {"name" : {"value" : "ivan","boost" : 10.0}}

вы можете обернуть его в логический запрос и повысить желаемый случай. бывший. найти все «иван», увеличить «джи» в поле имени.

{ "query" : { "bool" : { "must": [{"match":{"name":"ivan"}}],
"should" : [ { "term" : { "name" : { "значение" : "дзи", "увеличение" : 10 }}}]}}}

За исключением запроса термина, существует множество запросов, которые поддерживают ускорение, например prefix запрос, match запрос. Вы можете использовать его в ситуациях. Вот несколько официальных примеров: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_boosting_query_clauses.html

Повышение может оказаться непростым для контроля над оценкой, потому что оно требует нормализации. Вы можете указать оценку, используя запрос function_score, чтобы указать прямую оценку: Это действительно полезный запрос, если вам нужен более непосредственный контроль.


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

{ "query" : {
    "bool" : {
    "must": [
            {"filtered" : {
            "filter" : {
                "geo_distance" : {
                    "distance" : "2000km",
                    "loc" : {
                        "lat" : 10,
                        "lon" : 10
                    }
                }
            }
        }}],
    "should" : [ { "term" : { "name": { "value" : "ivan", "boost" : 10 }}}]}},
"sort" : [
            "_score",
    {
        "_geo_distance" : {
            "loc" : [10, 10],
            "order" : "asc",
            "unit" : "km",
            "mode" : "min",
            "distance_type" : "sloppy_arc"
        }
    }
]
}

Для получения более подробной информации вы можете проверить мою суть https://gist.github.com/hxuanji/e5acd9a5174ea10c08b8. Я повышаю имя "Иван". В результате документ "ivan" становится первым, а не документ (10,10).

person hxuanji    schedule 01.09.2014
comment
Спасибо за ваш ответ, однако мне все еще не ясно, как эта оценка будет работать с оценкой/результатами расстояния Geo. Результаты Geo сортируются по расстоянию, что, по-видимому, изменяет обычные функции подсчета очков. В таком случае повышение оценки приведет к неправильному измерению расстояния. Как же мне сохранить измерения Geo и при этом продвигать документ? - person kayatela; 01.09.2014
comment
Я предполагаю, что еще один способ приблизиться к этому — отсортировать результаты по _score (не по гео), но также включить данные _geo_distance в возвращаемые результаты. Но я так и не понял, как это сделать. - person kayatela; 01.09.2014
comment
Я не уверен, относится ли это к совершенно новому вопросу, но кто-нибудь знает, как преобразовать приведенный выше пример запроса в действительный SearchKick запрос? - person kayatela; 01.01.2015