Как отформатировать вывод (удалить данные сеанса) пользовательского запроса шифра с Neo4j::Session.query
Я использую Neo4jrb/Neo4j-core для пользовательских шифровальных запросов в моем приложении Rails. Я использую этот вывод как JSON. Тем не менее, каждый раз, когда я запускаю запрос
Например:
output_hash = Neo4j::Session.query("Match (n) return n limit 1;")
Наряду с результатами я также получаю много нежелательной информации о самой сессии.
Следующее включено для каждого узла.
"session": {
"connection": {
"parallel_manager": null,
"headers": {
"Content-Type": "application/json",
"User-Agent": "neo4j-gem/7.0.6 (https://github.com/neo4jrb/neo4j)"
},
"params": {},
"options": {
"params_encoder": null,
"proxy": null,
"bind": null,
"timeout": null,
"open_timeout": null,
"boundary": null,
"oauth": null
},
"ssl": {
"verify": null,
"ca_file": null,
"ca_path": null,
"verify_mode": null,
"cert_store": null,
"client_cert": null,
"client_key": null,
"certificate": null,
"private_key": null,
"verify_depth": null,
"version": null
},
"default_parallel_manager": null,
"builder": {
"handlers": [
{
"name": "Faraday::Request::BasicAuthentication",
"args": [
"neo4j",
"root"
],
"block": null
},
{
"name": "FaradayMiddleware::MultiJson::EncodeJson",
"args": [],
"block": null
},
{
"name": "FaradayMiddleware::MultiJson::ParseJson",
"args": [
{
"symbolize_keys": true,
"content_type": "application/json"
}
],
"block": null
},
{
"name": "Faraday::Adapter::NetHttpPersistent",
"args": [],
"block": null
}
],
"app": {
"header_value": "Basic bmVvNGo6cm9vdA==",
"app": {
"app": {
"app": {
"app": {}
},
"options": {
"symbolize_keys": true,
"content_type": "application/json"
},
"content_types": [
"application/json"
]
}
}
}
},
"url_prefix": {
"scheme": "http",
"user": null,
"password": null,
"host": "localhost",
"port": 7474,
"path": "/",
"query": null,
"opaque": null,
"fragment": null,
"parser": {
"regexp": {
"SCHEME": "(?-mix:\\A[A-Za-z][A-Za-z0-9+\\-.]*\\z)",
"USERINFO": "(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=A-Z_a-z~])*\\z)",
"HOST": "(?-mix:\\A(?:(?<IP-literal>\\[(?:(?<IPv6address>(?:\\h{1,4}:){6}(?<ls32>\\h{1,4}:\\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5]|\\d)\\.\\g<dec-octet>\\.\\g<dec-octet>\\.\\g<dec-octet>))|::(?:\\h{1,4}:){5}\\g<ls32>|\\h{,4}::(?:\\h{1,4}:){4}\\g<ls32>|(?:(?:\\h{1,4}:)?\\h{1,4})?::(?:\\h{1,4}:){3}\\g<ls32>|(?:(?:\\h{1,4}:){,2}\\h{1,4})?::(?:\\h{1,4}:){2}\\g<ls32>|(?:(?:\\h{1,4}:){,3}\\h{1,4})?::\\h{1,4}:\\g<ls32>|(?:(?:\\h{1,4}:){,4}\\h{1,4})?::\\g<ls32>|(?:(?:\\h{1,4}:){,5}\\h{1,4})?::\\h{1,4}|(?:(?:\\h{1,4}:){,6}\\h{1,4})?::)|(?<IPvFuture>v\\h+\\.[!$&-.0-;=A-Z_a-z~]+))\\])|\\g<IPv4address>|(?<reg-name>(?:%\\h\\h|[!$&-.0-9;=A-Z_a-z~])*))\\z)",
"ABS_PATH": "(?-mix:\\A\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*(?:\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*)*\\z)",
"REL_PATH": "(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])+(?:\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*)*\\z)",
"QUERY": "(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~\\/?])*\\z)",
"FRAGMENT": "(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~\\/?])*\\z)",
"OPAQUE": "(?-mix:\\A(?:[^\\/].*)?\\z)",
"PORT": "(?-mix:\\A[\\x09\\x0a\\x0c\\x0d ]*\\d*[\\x09\\x0a\\x0c\\x0d ]*\\z)"
}
}
},
"proxy": null
},
"resource_data": {
"extensions": {},
"node": "http://localhost:7474/db/data/node",
"relationship": "http://localhost:7474/db/data/relationship",
"node_index": "http://localhost:7474/db/data/index/node",
"relationship_index": "http://localhost:7474/db/data/index/relationship",
"extensions_info": "http://localhost:7474/db/data/ext",
"relationship_types": "http://localhost:7474/db/data/relationship/types",
"batch": "http://localhost:7474/db/data/batch",
"cypher": "http://localhost:7474/db/data/cypher",
"indexes": "http://localhost:7474/db/data/schema/index",
"constraints": "http://localhost:7474/db/data/schema/constraint",
"transaction": "http://localhost:7474/db/data/transaction",
"node_labels": "http://localhost:7474/db/data/labels",
"neo4j_version": "3.0.1"
},
"resource_url": "http://localhost:7474/db/data/"
}
Данные сеанса, кажется, содержат много конфиденциальной информации, и поэтому я не могу напрямую использовать вывод.
Я хотел бы избежать этого и просто получить простую и важную информацию для моих запросов на шифрование без дополнительной информации. Есть ли параметр конфигурации, который я могу использовать для этого?
Спасибо.
Обновление: я на самом деле использую Neo4jrb / Neo4j (который включает в себя ядро Neo4j) в качестве замены ActiveModel для нескольких основных задач в этом проекте. И пользовательские запросы для основных задач.
Дальнейшая проверка:
Пока модель ActiveNode определена, я получаю четкий ответ без каких-либо дополнительных (сеансовых) данных. Но возвращаются только свойства, определенные в файле модели.
class User
include Neo4j::ActiveNode
property :name, type: String
property :email, type: String
end
Это нормально работает для модели User, любые свойства, не объявленные в файле модели (но присутствующие в базе данных), по умолчанию игнорируются в соответствии с документацией.
Моя проблема: у моего графа есть определенные узлы, которые будут иметь много разных ключей свойств, которые нельзя заранее жестко закодировать в файл модели (причина использования БД без столбцов). Я не могу объявить все свойства этих узлов в модели.
Поэтому я пытаюсь выполнить пользовательский запрос шифрования как Neo4j::Session.query(q), но ответ JSON слишком хаотичен с данными сеанса. Обработка этого ответа с кодом приводит к запутанному коду, потому что кажется, что не существует согласованного способа, которым данные сеанса включаются между результатами (узлами, ребрами, агрегаторами).
Я ищу решение или выход.
2 ответа
Спасибо Брайан за вашу помощь. Чтобы подвести итог:
session
ключ в выходе, потому что Neo4j-core
по возможности возвращает соответствующий объект (узел / ребро), обратитесь к этой строке здесь в исходном коде. Оба класса CypherNode и CypherRelationship имеют переменную @session, и когда их объекты преобразуются в JSON/Hash/YAML, session
данные включаются автоматически.
Одним из вариантов является написание собственных пользовательских методов и расширение класса для более чистого вывода JSON. Брайан упоминает, что в следующем выпуске 8.0 будут представлены варианты синтаксиса в ответе. Или вы можете написать свой собственный код в своем приложении для обработки ответа от Neo4j-core
,
Я наконец закончил тем, что делал последнее как ниже:
class TestController < ApplicationController
def test
q = "Match (n) return n;"
data = Neo4j::Session.query(q)
output = clean_response(data)
render json: output
end
private
def clean_response(data)
# data = Enumerator
data = data.map(&:to_h)
# data = [ { x: => CypherXxxx <Object>},... ]
data.map! do |entry|
hash = JSON.parse(entry.to_json)
# Clean json of the entry
entry = delete_keys(hash)
end
end
def delete_keys(hash)
# Recursive func to delete session/response_hash from a hash of any depth
if(hash.class == Hash)
hash.delete("session") if hash.keys.include?("session")
hash.delete("response_hash") if hash.keys.include?("response_hash")
hash.each_value{|value|
value = delete_keys(value)
}
end
end
end
Хорошо, похоже, что может быть несколько вещей, происходящих;)
Во-первых, что касается неопределенных свойств, на самом деле здесь недавно был поток вопросов об этом:
https://github.com/neo4jrb/neo4j/issues/1209
На данный момент вы должны быть в состоянии использовать user._persisted_obj.props
получить все свойства для узла, даже если они не определены в ActiveNode
модель.
Что касается JSON, думаю, я понимаю, что вы говорите. Я думаю, на самом деле, что Enumerator
не очень хорошая поддержка рендеринга в JSON. Я видел, как у людей была эта проблема раньше, но она просто нажала, почему. А пока попробуйте:
render json: query_result_enumerator.map(&:to_h)
Это должно преобразовать в массив Hash
объекты и Hash, а также вложенные объекты node / rel должны поддерживать JSONified.