Solr 4.5: Расстояние до маршрута: сортировка или фильтрация

Работа с Solr 4.5 и вариант использования заключается в том, что мне нужно отсортировать результаты по расстоянию до заданного маршрута. Работа с документами, содержащими 1 геокоординату в качестве поля rpt geo (расположение точки интереса).

Вот иллюстрация того, к чему я стремлюсь: http://i.imgur.com/lGgMEal.jpg< /а> . Я хотел бы рассчитать кратчайшее расстояние от документа до заданного маршрута и использовать его в качестве повышающего компонента.

Текущая попытка состоит в том, чтобы использовать функцию {!score=recipDistance} в режиме edismax и отправить описание маршрута как LineString в WKT. Вот запрос, который отправляется сейчас:

fl=*,score,distdeg:query({!score=distance filter=false v=$spatialfilter})
defType=edismax
q.alt=*:*
boost=query({!score=distance filter=false v=$spatialfilter})
spatialfilter=geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869))"

И в форме URI:

http://sokemotortest:8080/solr/collection1/select?fl=*%2Cscore%2Cdistdeg%3Aquery%28{!score%3Ddistance+filter%3Dfalse+v%3D%24spatialfilter}%29&wt=json&debugQuery=true&defType=edismax&q.alt=*%3A*&boost=query%28{!score=distance%20filter=false%20v=$spatialfilter}%29&spatialfilter=geo:%22Intersects%28LINESTRING%20%2859.79619%2011.38690,%2060.25974%2011.63869%29%29%22

Мои проблемы с этим подходом:

  • Расстояние кажется рассчитанным от центра фигуры (маршрута). Это означает, что мы получаем дистанцию ​​не к линии, а к месту. С этим запросом это Pt(x=60.027965,y=11.512795)
  • Результаты расчета расстояния кажутся неверными. В указателе 4 документа, и они идут в следующем порядке:

    • (1) 59.7333, 7.61283
    • (2) 59.6236, 10.7263
    • (3) 59.6238, 10.7385
    • (4) 64.12379, 22.14029

    Когда порядок должен быть скорее:

    • (3) 59.6238, 10.7385
    • (2) 59.6236, 10.7263
    • (1) 59.7333, 7.61283
    • (4) 64.12379, 22.14029

Полный результат отладки boost calc можно посмотреть здесь: pastebin.com/5tvCb0Cf

Другим рабочим решением может быть фильтрация документов по расстоянию до маршрута (например: http://i.imgur.com/EJu8Kcg.jpg ). Это можно сделать с помощью буферизованной строки, которая поддерживается как в jTS, так и в space4j. Единственный вопрос заключается в том, как отправить буферизованную строку в качестве входных данных для функции Intersect (что-то вроде этого: geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869) d=1)").

Решением здесь было бы создание пользовательского компонента поиска, который будет принимать маршрут как LineString и перенаправлять запрос дальше как Polygon или MuliPolygon, но я бы предпочел избегать разработки пользовательских компонентов, если в этом нет необходимости.

Мои вопросы:

  • Возможно ли в Solr 4.5 получить расстояние до LineString, а не до центра фигуры?
  • Можем ли мы отправить буферизованную строку в качестве входных данных для функции Intersect (что-то вроде этого: geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869) d=1)")?

PS: Описание полей в индексе:

<field name="geo" type="location_rpt" indexed="true" stored="true"/>

Определение типа поля:

<fieldType name="location_rpt"
    class="solr.SpatialRecursivePrefixTreeFieldType"
    spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory" 
    geo="true"
    distErrPct="0.025"
    maxDistErr="0.000009"
    units="degrees"
    />

person Yon Yonson    schedule 21.10.2013    source источник


Ответы (1)


  1. Невозможно (без настройки Solr) получить расстояние до LineString запроса от индексированной точки для каждого документа. Вам нужно будет написать ValueSourceParser, который ссылается на строку lineString (которую вы можете проанализировать с помощью синтаксического анализатора JTS WKT), а также ссылается на ваше индексированное поле точки. В целях эффективного извлечения точки из документа для каждого документа используйте LatLonType, а не RPT. JTS может рассчитать расстояние между точкой и LineString, но имейте в виду, что JTS работает в евклидовом пространстве. Чтобы повысить точность, вам нужно «спроецировать» данные (как индексированную точку, так и строку строки) на проекцию, центр которой находится в строке строки. Proj4j может помочь с этим.

  2. RE bufferedLineStrings, вам может быть интересно узнать, что основная ветвь Spatial4j имеет форму «BufferedLineString» — она родная для Spatial4j. Однако он еще не интегрирован в парсинг формы, поэтому еще не полностью готов. Чтобы было ясно, он хорошо протестирован, и я использую его в частном порядке с парсером, исходный код которого не является открытым. Это также ограничено евклидовым пространством, как и JTS. Лучший способ приблизиться к этому — добавить собственный анализатор запросов Solr (проще, чем может показаться). Этот синтаксический анализатор запросов будет считывать буферное расстояние, LineString, и использовать оттуда JTS для его буферизации. Проецирование на центральную точку фигуры невозможно, поскольку оно должно совпадать с проиндексированными данными, поэтому вместо этого вы можете компенсировать это избыточной буферизацией на соответствующую величину, тем самым увеличив размер фигуры, но, по крайней мере, обеспечив захват минимального расстояния. У меня есть планы решить это лучше, но я был занят.

person David Smiley    schedule 21.10.2013
comment
Спасибо за быстрый и точный ответ Давид! Это отвечает на оба моих вопроса. Я рассмотрю возможность написания нового парсера запросов или, возможно, поискового компонента. - person Yon Yonson; 22.10.2013