Neo4j Spatial 'WithinDistance' Cypher-запрос возвращает пустой, а вызов REST возвращает данные

У меня есть то, что кажется правильно настроенным пространственным слоем и индексом, и я могу успешно запросить узел с помощью вызова API REST findGeometriesWithinDistance.

POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance {"layer":"geom","pointX":15.0,"pointY":60.0,"distanceInKm":100.0}

Однако при запросе с использованием cypher я не получаю результатов (я попытался изменить порядок 60.0 и 15.0 без удачи):

START n=node:geom('withinDistance:[60.0, 15.0, 500.0]') return n;

Сайпер возвращается:

==> +---+
==> | n |
==> +---+
==> +---+
==> 0 row
==> 
==> 13 ms

ОСТАЛЬНОЕ:

200 OK
==> [ {
==>   "paged_traverse" : "http://localhost:7474/db/data/node/14472/paged/traverse/{returnType}{?pageSize,leaseTime}",
==>   "outgoing_relationships" : "http://localhost:7474/db/data/node/14472/relationships/out",
==>   "data" : {
==>     "lon" : 15.2,
==>     "bbox" : [ 15.2, 60.1, 15.2, 60.1 ],
==>     "RaceName" : "Parador Es Muy Caliente",
==>     "lat" : 60.1,
==>     "gtype" : 1
==>   },
==>   "all_typed_relationships" : "http://localhost:7474/db/data/node/14472/relationships/all/{-list|&|types}",
==>   "traverse" : "http://localhost:7474/db/data/node/14472/traverse/{returnType}",
==>   "self" : "http://localhost:7474/db/data/node/14472",
==>   "all_relationships" : "http://localhost:7474/db/data/node/14472/relationships/all",
==>   "property" : "http://localhost:7474/db/data/node/14472/properties/{key}",
==>   "properties" : "http://localhost:7474/db/data/node/14472/properties",
==>   "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/14472/relationships/out/{-list|&|types}",
==>   "incoming_relationships" : "http://localhost:7474/db/data/node/14472/relationships/in",
==>   "incoming_typed_relationships" : "http://localhost:7474/db/data/node/14472/relationships/in/{-list|&|types}",
==>   "extensions" : {
==>   },
==>   "create_relationship" : "http://localhost:7474/db/data/node/14472/relationships"
==> } ]

REST Вызывает воспроизведение: Создать слой:

POST /db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer { "layer":"geom", "lat":"lat", "lon":"lon" }

Создать индекс:

POST /db/data/index/node/ {"name":"geom", "config":{"provider":"spatial", "geometry_type":"point","lat":"lat","lon":"lon"}}

Создать узел:

POST /db/data/node {"lat":60.2,"lon":15.1,"RaceName":"Parador Es Muy Caliente"}

(В ответ проверьте "self" и найдите nodeid)

Индексировать узел:

POST /db/data/ext/SpatialPlugin/graphdb/addNodeToLayer {"layer":"geom", "node":"http://localhost:7474/db/data/node/###NEW_NODE_ID###"}

Найти:

POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance {"layer":"geom","pointX":15.0,"pointY":60.0,"distanceInKm":100.0}

2 ответа

Я исследовал это, и это связано с проблемой, которую мы видели несколько раз. Существует несоответствие в дизайне пространственной библиотеки в том, что есть два способа добавить узел в пространственный индекс. Один из них - добавить его в слой (используя вызов REST addNodeToLayer), и для этого используется базовый Java API, который напрямую соединяет узел с RTree как часть того же графа. Другой - создать прокси-узел в графе индекса, чтобы ваш домен не был связан с графом индекса. Этот второй подход используется только интерфейсом IndexProvider (с использованием вызова REST / db / data / index / node / geom).

Если вы вызываете оба метода, узел добавляется дважды, один раз напрямую и один раз по доверенности. Проблема заключается в том, что запрос индекса Cypher WithinDistance обращается только к интерфейсу IndexProvider и возвращает только узлы, которые НЕ связаны с индексом. Таким образом, если вы добавите узел обоими способами, он не будет возвращен.

Так что вам нужно добавить его только одним из двух способов. Я не видел в вашем исходном письме никаких упоминаний о addNodeToLayer, поэтому я подозреваю, что SDN может вызывать addNodeToLayer (возможно, Майкл может комментировать), и в этом случае вы не можете использовать вызов cypher.

Во время тестирования я смог вручную удалить одноиндексное отношение с помощью Cypher:

START n = узел (13065) MATCH (n)<- [r: RTREE_REFERENCE] - () УДАЛИТЬ r

Замените число 13065 на ваш идентификатор узла для исходного узла.

Я сделал следующее в браузере neo4j (в 2.1.2):

:POST /db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer { "layer":"geom", "lat":"lat", "lon":"lon" }
:POST /db/data/index/node/ {"name":"geom", "config":{"provider":"spatial", "geometry_type":"point","lat":"lat","lon":"lon"}}
:POST /db/data/node {"lat":60.2,"lon":15.1,"RaceName":"Parador Es Muy Caliente"}
:POST /db/data/index/node/geom {"value":"dummy","key":"dummy", "uri":"http://localhost:7474/db/data/node/13071"}

Это создало граф с узлом, не подключенным напрямую к индексу. В этом случае вызов REST 'findGeometriesWithinDistance' не работает (использует стандартный API Java), в то время как шифр 'WithinDistance' работает. Я проверил с этой командой:

start n = node:geom("withinDistance:[60.2,15.1,100.0]") return n

Обратите внимание, что, к сожалению, этот API устанавливает порядок как lat,lon вместо более стандартного lon, lat.

Затем я также добавил к слою (то есть добавить непосредственно в график индекса):

:POST /db/data/ext/SpatialPlugin/graphdb/addNodeToLayer {"layer":"geom", "node":"http://localhost:7474/db/data/node/13071"}

Теперь, когда я ищу с помощью команды cypher, я все равно получаю тот же правильный ответ, но когда я ищу с помощью команды REST:

:POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance {"layer":"geom","pointX":15.0,"pointY":60.0,"distanceInKm":100.0}

Я считаю, что это возвращает прокси-узел вместо исходного узла.

Это ошибка, см. https://github.com/neo4j/spatial/issues/106 если хотите, не стесняйтесь исследовать, похоже, итерация в SpatialRecordHits.java!

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

Другие вопросы по тегам