2015-03-12 2 views
0

Я хотел бы знать, что говорит название.Возможно ли выполнение запросов cypher только для чтения из java?

Причина, по которой я хочу, чтобы это разрешалось, чтобы выполнялись только запросы cypher только для чтения; результаты данных впоследствии будут интерпретироваться и сериализоваться отдельным слоем API.

Я видел код, который делает основные допущения в попытке воспроизвести это поведение, например. код может отфильтровать любой запрос Cypher, содержащий определенные специальные слова, связанные с структурами запросов записи (merge, create, delete, set и т. д.).

Этот подход имеет тенденцию быть ограниченным и наивным; если он просто ищет эти жетоны, он предотвратит такой запрос, как MATCH n WHERE n.label =~ '.*create.*' RETURN n, хотя это запрос только для чтения.

Я бы предпочел не выполнять полный анализ запроса кандидата, а затем спуститься через AST, пытаясь выяснить, доступно ли что-то только для чтения (хотя я с радостью принимаю ответ, который показывает, как это сделать это легко в Java)

EDIT - Я знаю, что это возможно, чтобы запустить всю базу данных в режиме только для чтения с помощью свойства конфигурации read_only=true, но это было бы нежелательно; ни один другой аспект API java не сможет изменить базу данных.

EDIT 2 - Я нашел еще одну возможную стратегию, но я не уверен в ее целесообразности. Комментарии приветствуются на этом, и потенциальные недостатки:

try (Transaction ignore = graphDb.beginTx()) { 
    ExecutionResult result = executionEngine.execute(query); 
    // Do nifty stuff with result, then... 

    // Force transaction to fail. 
    ignore.failure(); 
} 

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

+1

Я не знаю о такой возможности, но любопытно узнать, есть ли способы. Так как Neo4j 2.2 вводит базовый auth, я бы ожидал, что они вскоре представит несколько пользователей и ролевой доступ, функции, которые требуются в течение длительного времени. Это не то, что можно легко закрепить снаружи, и я слышал, что это должно быть достаточно простым в их (внутренних) API. – albertoperdomo

+0

Я обновил второе редактирование - одну возможность. Не уверен, насколько это разумно. – FrobberOfBits

ответ

1

Только для чтения Cypher (еще не поддерживается). Однако я могу придумать два обходных пути для этого:

1) если вы используете кластер Neo4j: вы можете установить read_only=true на один экземпляр. Этот экземпляр затем используется для запросов только для чтения, где другие экземпляры кластера используются для r/w. Балансировщик нагрузки перед кластером может быть настроен для отправки запросов в соответствующий экземпляр.

2) Используйте TransactionEventHandler, который vetos совершает транзакцию, если ее TransactionData содержит операции записи. Просто для удовольствия я вложил несколько минут, чтобы реализовать это, см. https://github.com/sarmbruster/read-only-cypher - отзывы приветствуются.

+0

Спасибо - я проверю этот код. Что вы думаете о подходе «намеренно не справляетесь с транзакциями»? (Редактировать 2 в сообщении) – FrobberOfBits

+1

«намеренно не удается выполнить транзакцию» будет работать для встроенного использования. Однако вы не можете подключиться к конечной точке Cypher при развертывании сервера с помощью этого подхода. –

Смежные вопросы