Gremlin / Bulbflow: Как выбрать узлы на основе их ребер и связанных свойств вершины

Извините за длинный пост, но я хочу избежать недоразумений по поводу того, что я ищу:)

В настоящее время я изучаю графовые базы данных и немного экспериментирую с bulbflow/neo4j. Таким образом, я пытаюсь использовать gremlin для большинства моих запросов, но я не знаю, выполним ли желаемый запрос или нет. Возможно, я даже ошибаюсь, пытаясь использовать graph db для такого случая, поэтому не стесняйтесь говорить мне, считаете ли вы, что я на правильном пути или нет.

Во-первых, позвольте мне предоставить немного контекста:

Я работаю над проектом с открытым исходным кодом на ранней стадии, который является компилятором для языка DSL, генерирующего C-код. В настоящее время мы планируем переписать все это на python по многим причинам (язык, перепроектирование, открытие для сообщества и т. Д.). Компилятор включает в себя то, что я назову кешем скомпилированных интерфейсов и шаблонов. Интерфейсы описывают шаблоны, и каждый шаблон связан с конфигурацией (список типизированных значений, связанных с переменными, описанными интерфейсами).

Цель запроса, который я хочу построить, состоит в том, чтобы выбрать реализацию одного шаблона в зависимости от входной конфигурации (фактически используемой в механизме генерации компилятора). В конце я хочу иметь возможность напрямую запрашивать через gremlin (если вообще возможно) единственный элемент, который я ищу, чтобы обеспечить уникальность для элементов, которые можно найти в этом "кэше". В настоящее время я вручную сопоставляю эту конфигурацию в коде python, но я хочу знать, возможно ли сделать это непосредственно в gremlin.

-

Итак, давайте определим пример графика для моего варианта использования: у нас есть три типа вершин:

  1. Def (определение), содержит свойство String с именем "signature", которое фактически является подписью шаблона, определенного этим узлом.
  2. Impl (реализация), содержащая два свойства, которые являются путями к исходному и предварительно скомпилированным файлам.
  3. Var (переменная), содержащая свойство String, которое является сигнатурой переменной.

Затем несколько видов ребер:

  • Def -> impl_by -> Impl (для определения может существовать несколько реализаций, не содержащее никаких свойств)
  • Impl -> select_by -> Var (Реализации могут быть выбраны через ограничение по значению переменной конфигурации, каждое ребро этого типа содержит фактически три свойства: тип, значение и ограничение - оператор сравнения -)

Край selected_by (или отношение, следующее за словарем bulflow) описывает ограничение выбора и, таким образом, имеет следующие свойства:

  • val (значение, связанное с переменной для реализации источника)
  • op (оператор сравнения, указывающий, какой тип сравнения сделать, чтобы ограничение было действительным или нет)

Это переводится как график, такой как (я опущу типы от краев selected_by на этом графике):

              -- select_by { value="John", op="="}  ---------
              |                                              \
    (1)--Impl--- select_by { value=12, op=">"}      ------    \
    |                                                     \    \
    |                                                      \    |- Var("name")
    |         |- select_by { value="Peter", op="="} -----------/
Def (2)--Impl--                                              \/
    |         |- select_by { value=15, op="<"}      ----     /\
    |                                                   \   /  \
    |                                                    |-/----|--- Var("ver")
    (3)--Impl--- select_by { value="Kat", op="!="}  ------/    /
            |                                                 /
            |--- select_by { value=9, op=">"}       ---------/

Что я хочу сделать, это выбрать один (или несколько) Impl в зависимости от их отношений с Vars. Допустим, у меня есть конфигурация следующим образом:

Конфиг 1:

variable="name", value="Peter"
variable="ver", value=16

Это выберет Impl(3), поскольку Peter!= Kat AND 16 > 9, но не Impl(1), так как Peter!= John и Impl(2) с 16!< 15.

Я был заблокирован на нескольких уровнях, поэтому я начал задаваться вопросом, было ли это вообще возможно:

  • Я не мог найти, как передать такие аргументы (конфигурацию) скрипту gremlin.
  • Я не мог найти, как выбрать Impl на основе условий на исходящих ребрах.

Надеюсь, это не слишком запутанно.

Ура и спасибо!

РЕДАКТИРОВАТЬ:

Мне удалось заставить часть моего запроса работать с помощью многократного возврата и фильтров. Запрос (X - начальная вершина, VALUE - значение, которое я хочу сопоставить, и NAME - имя переменной для сопоставления) выглядит следующим образом:

Основа запроса:

g.v(X).out('impl').as('implem')

Повторите эту часть для каждой пары VALUE/NAME:

.out('select_by').filter{it.value=='VAL‌​UE'}
.inV('select_by').filter{it.name=='NAME'}
.back('implem')

Единственное, чего сейчас не хватает, так это того, что я не знаю, как использовать свойство 'op' края select_by, чтобы определить, как создать фильтр для использования. Например, есть случаи, когда я хочу в точности соответствовать конфигурации (и, таким образом, как в этом запросе, я игнорирую свойство 'op'), но есть случаи, когда я хочу принять во внимание свойство 'op', и используйте связанный фильтр в фильтрах.

Есть ли способ сделать это? (Или я должен отправить другой вопрос?)

0 ответов

Другие вопросы по тегам