2015-12-21 5 views
2

У меня есть огромная база данных с авторами, которые связаны с документами и документами, связанными с узлами, которые содержат метаинформацию статьи. Я попытался выбрать авторов, которые соответствуют определенному шаблону, и поэтому я выполнил следующую инструкцию 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); 
} 

ответ

2

Ваш запрос использует регулярное выражение, и, следовательно, не в состоянии использовать индекс:

MATCH (n:AUTHOR) WHERE n.name =~ '(?i).*jim.*' RETURN n 

Neo4j 2,3 введен индекс, поддерживаемый STARTS WITH оператор строки так, этот запрос будет очень производительным:

MATCH (n:Author) WHERE n.name STARTS WITH 'jim' RETURN n 

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

+0

Таким образом, обычно 'CONTAINS' должен также иметь возможность использовать индекс? Но если я использую 'CONTAINS', как описано в руководстве, я всегда получаю ошибку: Недопустимый вход 'O': ожидаемый 'r/R' (строка 1, столбец 32 (смещение: 31)) " MATCH (n : AUTHOR) ГДЕ n.name СОДЕРЖИТ 'jim' RETURN n; " –

+0

В настоящее время я считаю, что только 'STARTS WITH' использует индекс (а не' CONTAINS' или 'ENDS WITH'). Вы можете проверить это, добавив «ПРОФИЛЬ» или «ОБЪЯСНЕНИЕ» в свой запрос и работая в браузере Neo4j, чтобы увидеть план выполнения. –

+0

Какую версию Neo4j вы используете? 'CONTAINS',' STARTS WITH' и 'ENDS WITH' были добавлены в 2.3 –

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