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!
Между тем, убедитесь, что добавили узел в индекс, прежде чем выполнять запросы через индекс, поскольку это создает правильную структуру узла.