Индексация Neo4j (с Lucene) - хороший способ организовать "типы" узлов? - PullRequest
5 голосов
/ 27 марта 2012

На самом деле это скорее вопрос Lucene, но это в контексте базы данных neo4j.

У меня есть база данных, которая поделена на около 50 типов узлов (например, «коллекции» или «таблицы»).в других типах БД).У каждого есть подмножество свойств, которые необходимо проиндексировать, некоторые имеют одно и то же имя, некоторые - нет.

При поиске я всегда хочу найти узлы определенного типа, а не по всем узлам.

Я вижу три способа организации этого:

  • Один индекс для каждого типа, свойства естественным образом отображаются в индексные поля: index 'foo', 'id'='1234'.

  • Один глобальный индекс, каждое поле сопоставляется с именем свойства, чтобы различать тип, либо включать его как часть значения ('id'='foo:1234'), либо проверять узлы после их возвращения (я ожидаюдубликаты встречаются очень редко).

  • Один тип индекса является частью имени поля: 'foo.id'='1234'.

После создания,база данных доступна только для чтения.

Есть ли какие-либо преимущества для одного из них с точки зрения удобства, эффективности размера / кэша или производительности?

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

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Я столкнулся с этой проблемой недавно, когда создавал адаптер соединения ActiveRecord для Neo4j поверх REST, который будет использоваться в проекте Rails.Поскольку оба ActiveRecord и ActiveRelation тесно связаны с синтаксисами SQL, стало трудно вписать все в NoSQL.Возможно, это не лучшее решение, но вот как я его решил:

  1. Создан индекс с именем model_index, который индексировал узлы под двумя ключами, type и model
  2. Поиск индекса с ключом type в настоящее время происходит только с одним значением model.Это было введено в первую очередь для достижения SHOW TABLES функциональности SQL, которая может дать мне список всех моделей, представленных на графике.
  3. Поиск индекса с ключом model происходит со значениями, соответствующими различным именам моделей в моемсистема.Это в первую очередь для достижения функциональности DESC <TABLENAME>.
  4. При каждом создании таблицы, как в CREATE TABLE, создается узел с атрибутами определения таблицы, хранящимися в свойствах узла.
  5. Созданный узел индексируетсяпод model_index с type:model и model:<model-name>.Это позволяет вновь созданной модели в списке «таблиц», а также позволяет напрямую обращаться к узлу модели с помощью поиска по индексу с помощью клавиши model.
  6. Для каждой записи, созданной для model (введитев вашем случае), создается исходящий фронт с пометкой instances, направленный от узла модели к этой новой записи.v[123] :=> [instances] :=> v[245] где v [123] представляет узел модели, а v [245] представляет запись типа v [123].
  7. Теперь, если вы хотите получить все экземпляры указанного типа, вы можете искатьmodel_index с model:<model-name> для достижения узла модели и затем извлечения всех смежных узлов по исходящему ребру, помеченному instances.Отфильтрованные поиски могут быть дополнительно достигнуты путем применения фильтров и других сложных обходов.

Приведенное выше решение предотвращает засорение model_index, поскольку оно содержит 2x и обеспечивает эффективный поиск записей с помощью одного просмотра индекса и одноуровневого обхода.

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

В настоящее время я перевожу скрипты AREL в Gremlin почти для всего.Вы можете найти исходный код моего адаптера AR на https://github.com/yournextleap/activerecord-neo4j-adapter

Надеюсь, это поможет, ура!:)

1 голос
/ 27 марта 2012

spring-data-neo4j использует первый подход - он создает разные индексы для каждого типа.Так что я думаю, что это хороший вариант для общего сценария.Но в вашем конкретном случае это может быть неоптимальным, как вы говорите.Я бы провел несколько тестов для измерения производительности.

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

1 голос
/ 27 марта 2012

Один индекс будет меньше, чем несколько маленьких индексов, потому что некоторые данные, такие как словарь терминов, будут общими. Однако, так как поиск по словарю терминов является операцией O (lg (n)), поиск в словаре с большим термином может быть немного медленнее. (Если у вас 50 индексов, для этого потребуется только 6 (2 ^ 6> = 50) сравнений, скорее всего, вы не заметите никакой разницы.)

Еще одним преимуществом меньшего индекса является то, что кэш ОС, вероятно, ускоряет выполнение запросов.

Вместо ваших вариантов 2 и 3 я бы проиндексировал два разных поля id и type и произвел бы поиск (id: ID AND type: TYPE), но я не знаю, возможно ли это с neo4j.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...