Статьи

По индексам Neo4j, совпадение и слияние

Мы в Neo4j делаем все возможное, чтобы сбить с толку наших пользователей. Я говорю об индексах моих друзей.
Мои доверенные коллеги Найджел Смолл — Index Confusion и Стефан Армбрустер — Indexing, Overview уже проделали большую работу, объясняя ситуацию с индексированием в Neo4j. Я хочу добавить еще несколько аспектов здесь.

После выпуска Neo4j 2.0 и введения индексов схемы мне приходилось отвечать на растущее число вопросов, возникающих из-за путаницы между двумя доступными в настоящее время типами индексов: индексами схемы и устаревшими индексами .
Для пояснения, это две совершенно разные концепции, которые не являются взаимозаменяемыми или совместимыми.
Поэтому важно убедиться, что вы знаете, какой вы используете.


— Найджел Смолл

Почему мы вообще индексируем в базе данных графов, разве мы не все о графической навигации?
Чтобы быстро найти начальные точки для вашего обхода графа или совпадения с образцом.

Индексы схемы

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

Примечание: только индексы схемы осведомлены о метках; унаследованные индексы совершенно и совершенно не знают о метках.

Дальнейшее примечание: индексы схемы также доступны только для узлов, тогда как унаследованные индексы позволяли также индексировать отношения.
Вариантов использования для индексации отношений было немного, и их можно было обойти, введя дополнительные узлы.


— Найджел Смолл

Сегодня Neo4j использует точные, чувствительные к регистру индексы и ограничения автоматической схемы, основанные на одной метке и одном свойстве.
Метки и индексы являются частью «необязательной» схемы схемы Neo4j.

Схемы индексов и МАТЧ

Вы создаете индекс схемы с помощью, CREATE INDEX ON :Label(property)например CREATE INDEX ON :Person(name).

Вы список доступных индексов схемы (и ограничения) , а также их статус ( POPULATING, ONLINE, FAILED) с :schemaв браузере или schemaв оболочке.

Всегда следите за тем, чтобы индексы и ограничения, которые вы хотите использовать в своих операциях, были ОНЛАЙН, иначе они не будут использоваться и ваши запросы будут медленными.

Когда вы создаете новый индекс схемы, он также асинхронно индексирует все существующие узлы с этой комбинацией метки и свойства.

После того, как индекс будет доступен, он будет отображаться как «ONLINE». Более поздние изменения узлов (добавление и удаление меток и обновление свойств) также автоматически и транзакционно отражаются в индексе.

Вы можете дождаться создания индекса с помощью schema await.


Запись
Полнотекстовые, пространственные и составные индексы схемы недоступны с Neo4j 2.2.

Вам нужен индекс или ограничение для эффективного поиска начальных узлов через MATCH, в противном случае Neo4j должен выполнить полное сканирование меток со сравнением свойств, чтобы найти ваш узел, который может быть очень дорогим.

Индексы схемы будут использоваться как для встроенного синтаксиса, MATCH (p:Person {name:"Mark"})так и для WHEREусловий, MATCH (p:Person) WHERE p.name="Mark"а также для предикатов IN MATCH (p:Person) WHERE p.name IN ["Mark","Max"].

Neo4j использует индексы схемы автоматически, но вы можете принудительно использовать определенные индексы с помощью подсказок, как USING INDEX p:Person(name)после MATCHпредложения.

Вы можете проверить, что Neo4j действительно использует индекс, добавив к запросу префикс EXPLAINи посмотрев на визуализацию плана запроса.
Он должен показывать NodeIndexSeekвместо NodeByLabelScan+Filter

Помните, что для поиска учитывается только одно свойство и только метка, для которой вы определили индекс!

Ограничения и MERGE

MERGEОперация также будет использовать индекс для ускорения операций поиска, но индекс не гарантирует уникальность узлов.

Вот где вступают в силу уникальные ограничения , опять же для одного ярлыка и одного свойства.
Вы создаете их с этим громоздким синтаксисом CREATE CONSTRAINT ON (n:Label) ASSERT n.property IS UNIQUE, напримерCREATE CONSTRAINT ON (b:Book) ASSERT b.isbn IS UNIQUE

Ограничения при создании проверят все узлы в базе данных с этой комбинацией метки и свойства на уникальность и потерпят неудачу, если есть дубликаты, и выведут их список.
Создание ограничения блокирует.
Он вернется только после того, как ограничение было успешно создано («ONLINE») или отменено («FAILED»).

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

Уникальные ограничения гарантируют, что никакая другая операция не создаст узел с двойной комбинацией метка + свойство-значение из-за сбоя транзакции с исключением.
Это касается всех операций, таких как CREATEузел, SETзначение свойства, ADDметка, а также вызовов через Java-API.

MERGEиспользует ограничения для эффективного поиска и проверки уникальности, а также получения сфокусированной блокировки, которая гарантирует уникальность даже в параллельных операциях и в кластере.

Если вам нужно установить другие свойства как часть создания вашего узла, используйте ON CREATE SETопцию:
MERGE (b:Book {isbn:{isbn}}) ON CREATE SET p.title = {title}, p.year = {year}


Запись
Другие типы ограничений, например свойство (тип) или составные ограничения, недоступны с Neo4j 2.2

Составные ограничения (и индексы)

Если вам действительно нужны ограничения составного ключа или поиск индекса, рассмотрите возможность объединения значений в искусственное свойство id или используйте массив с этими составными значениями как «id». Например:

CREATE CONSTRAINT ON (a:Address) assert a.composite_id IS UNIQUE;

MERGE (a:Address {composite_id: [{zip},{street},{number}]}) ON CREATE SET a.zip = {zip}, a.street={street}, a.number = {number};

// or

MERGE (a:Address {composite_id: {zip}+"_"+{street}+"_"+{number}}) ON CREATE SET a.zip = {zip}, a.street={street}, a.number = {number};

Ручные (устаревшие, устаревшие) индексы

До выхода Neo4j 2.0 унаследованные индексы просто назывались индексами. Они работали на Lucene вне графика и позволяли индексировать узлы и отношения в паре ключ: значение. С точки зрения интерфейса REST, большинство вещей, называемых «индексами», все еще будут ссылаться на эти устаревшие индексы.

Примечание. Устаревшие индексы обычно использовались в качестве указателей для начала узлов для запроса; они не предоставили автоматическую возможность ускорить запросы.


— Найджел Смолл

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


Запись
Если вам не нужен полнотекстовый, пространственный индекс или индекс отношений или вам не нужно иметь дело с «устаревшим» приложением Neo4j, вы можете их игнорировать .
Хватит читать здесь.

Вы должны были добавить узлы и отношения (с ключом и значением) в именованный индекс самостоятельно, поэтому они называются «ручными индексами».

Эти индексы были точными или полнотекстовыми индексами Lucene для узлов или отношений или пространственными индексами для узлов.

Индексы Lucene также опционально отображали синтаксис запросов lucene и имели настраиваемые наблюдения и анализаторы.

Вы можете использовать ручные индексы через Java API или через STARTпредложение в Cypher, например
START post=node:posts("title:Graphs") match (post)←[:WROTE]-(author) RETURN post,author

Вы управляете ими с помощью indexкоманды в оболочке, вы перечисляете их с помощью index --indexes.

В старом интерфейсе Webadmin есть также вкладка, в которой они перечислены.

Унаследованные индексы также имели опции для создания уникальных узлов и отношений, которые теперь заменены MERGE с CONSTRAINTs .

Устаревшие авто-индексы

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

Вы можете настроить ровно один автоматический индекс для всех узлов ( node_auto_index) и один для всех связей ( relationship_auto_index), перечислив свойства, которые должны быть проиндексированы.

Вы можете использовать их снова с Java API и STARTпредложением, но на этот раз с фиксированным _auto_indexименем (см. Выше).

Вы по-прежнему можете найти параметры конфигурации в файле `neo4j.properties`config, а также API-интерфейсы как в Java, так и в конечных точках REST.
Все это безопасно игнорировать , кроме случаев, когда вы знаете, что делаете, и хотите попробовать использовать автоматический пространственный или полнотекстовый индекс.
Имейте в виду, что это сложный бизнес.

Так что я должен использовать?

Если вы используете Neo4j 2.0 или выше и вам не нужно поддерживать устаревший код, относящийся к эпохе до 2.0, используйте только индексы схемы и избегайте устаревших индексов.
И наоборот, если вы застряли с более ранней версией Neo4j и не можете выполнить обновление, у вас все равно есть только один тип индекса.

Если вам нужна полнотекстовая индексация, независимо от версии Neo4j, вам придется использовать устаревшие индексы.

Более сложные сценарии включают период перехода от одного типа индекса к другому.
В этих случаях убедитесь, что вы полностью осведомлены о различиях, и по возможности старайтесь использовать схемы или устаревшие индексы, но не оба.
Смешивание двух часто приводит к еще большей путанице.


— Найджел Смолл

А если сомневаетесь, задайте вопрос в списке рассылки Neo4j или в StackOverflow .