У меня есть огромная база данных с авторами, которые связаны с документами и документами, связанными с узлами, которые содержат метаинформацию статьи. Я попытался выбрать авторов, которые соответствуют определенному шаблону, и поэтому я выполнил следующую инструкцию cypher в java.Neo4j медленный запрос cypher во встроенном режиме
String query = "MATCH (n:AUTHOR) WHERE n.name =~ '(?i).*jim.*' RETURN n";
db.execute(query);
Я получаю результатСеть со всеми «авторами» назад. Но исполнение происходит очень медленно. Это потому, что Neo4j записывает результат в память?
Если я попытаюсь найти узлы с Java API, это намного быстрее. Конечно, я могу найти точное имя, например, следующий пример кода, но это примерно на 4 секунды быстрее, чем запрос выше. Я протестировал его в небольшой базе данных с примерно 50 узлами, в которой только 6 из них являются авторами. Шесть авторов также находятся в индексе.
db.findNodes(NodeLabel.AUTHOR, NodeProperties.NAME, "jim knopf");
Есть ли шанс ускорить шифр? Или возможность получить все узлы через API Java и метод findNodes()
, который соответствует заданному шаблону?
Просто для информации, я создал индекс для имени автора в Java с graph.schema().indexFor(NodeLabel.AUTHOR).on("name").create();
Возможно, кто-то может помочь. Заранее спасибо.
EDIT:
Я бегу некоторые тесты сегодня. Если я выполняю запрос PROFILE MATCH (n:AUTHOR) WHERE n.name = 'jim seroka' RETURN n;
в интерфейсе браузера, у меня есть только оператор NodeByLabelScan. Мне кажется, что Neo4j не использует автоматический индекс (индекс для имени онлайн). Если я использую конкретный индекс и выполняю запрос PROFILE MATCH (n:AUTHOR) USING INDEX n:AUTHOR(name) WHERE n.name = 'jim seroka' RETURN n;
, этот индекс будет использоваться. Обычно Neo4j должен автоматически использовать правильный индекс. Существует ли какая-либо конфигурация?
Я также проверил несколько тестов во встроенном режиме, чтобы проверить производительность запроса во встроенном режиме. Я попытался выбрать автора «jim seroka» с db.findNode(NodeLabel.AUTHOR, "name", "jim seroka");
. Это работает, и мне кажется, что этот индекс используется из-за времени выполнения ~ 0,05 секунд.
Но если я запустил тот же запрос, как я выполнил в интерфейсе и упомянутый выше, используя определенный индекс, он занимает ~ 4,9 секунды. Зачем? Я немного беспомощна. База данных является локальной и насчитывает всего 6 авторов. Является ли разъем медленным или неправильным создание соединения? OK, findNode()
действительно возвращает только узел и выполняет весь результат, но разница в четыре секунды?
Следующий исходный код должен показать, как будет создана база данных и выполняется запрос.
public static GraphDatabaseService getNeo4jDB() {
....
return new GraphDatabaseFactory().newEmbeddedDatabase(STORE_DIR);
}
private Result findAuthorNode(String searchValue) {
db = getNeo4jDB();
String query = "MATCH (n:AUTHOR) USING INDEX n:AUTHOR(name) WHERE n.name = 'jim seroka' RETURN n";
return db.execute(query);
}
Таким образом, обычно 'CONTAINS' должен также иметь возможность использовать индекс? Но если я использую 'CONTAINS', как описано в руководстве, я всегда получаю ошибку: Недопустимый вход 'O': ожидаемый 'r/R' (строка 1, столбец 32 (смещение: 31)) " MATCH (n : AUTHOR) ГДЕ n.name СОДЕРЖИТ 'jim' RETURN n; " –
В настоящее время я считаю, что только 'STARTS WITH' использует индекс (а не' CONTAINS' или 'ENDS WITH'). Вы можете проверить это, добавив «ПРОФИЛЬ» или «ОБЪЯСНЕНИЕ» в свой запрос и работая в браузере Neo4j, чтобы увидеть план выполнения. –
Какую версию Neo4j вы используете? 'CONTAINS',' STARTS WITH' и 'ENDS WITH' были добавлены в 2.3 –