Как реализовать это в python: проверьте, существует ли вершина, если нет, создайте новую вершину

Я хочу создать базу данных neptune и сбросить в нее данные. Я загружаю исторические данные из DynamoDB в S3, эти файлы в формате csv. Заголовок в этих csv вроде:

~id, someproperties:String, ~label

Затем мне нужно реализовать потоковую передачу в реальном времени в этот neptune db через лямбда, в лямбда-функции я проверю, существует ли одна вершина (или ребра) или нет, если существует, я обновлю вершину (или ребра), в противном случае Создаю новый. В python моя реализация выглядит так:

g.V().hasLabel('Event').has(T.id, event['Id']).fold().coalesce(unfold(), addV('Event').property(T.id, event['Id'])).property(Cardinality.single, 'State', event['State']).property('sourceData', event['sourceData']).next()

У меня есть несколько вопросов:

  1. При потоковой передаче в реальном времени мне нужно запросить, есть ли вершина с идентификатором, поэтому мне нужно запросить узлы исторических данных, так можно ли has(T.id, event['Id']) это сделать? или мне просто использовать has(id, event['Id']) или has("id", event['Id'])?
  2. Я использовал g.V().has('Event', T.id, event['Id']) вместо g.V().hasLabel('Event').has(T.id, event['Id']), но получил ошибку типа cannot local NeptuneGraphTraversal.has(). Эти два запроса одно и то же?

person Hongli Bu    schedule 02.10.2019    source источник


Ответы (1)


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

g.V().has(T.id, "some-id")
g.V().has(id, "some-id")
g.V().has("id", "some-id")

Первые два вернут вам тот же результат, что и id является членом T (как правило, пользователи Gremlin обычно статически импортируют id, чтобы на него можно было ссылаться таким образом для краткости). Последний обход отличается от первых двух, потому что в качестве значения String он ссылается на стандартный ключ свойства с именем «id». Вообще говоря, TinkerPop рекомендует не использовать имя ключа свойства, такое как «id» или «label», поскольку это может привести к ошибкам и путанице со значениями T.

Что касается второй части вашего вопроса:

g.V().has('Event', T.id, event['Id']) 
g.V().hasLabel('Event').has(T.id, event['Id'])

Вы не можете передать T.id в трехзначную форму has(), как указывает Кельвин, поскольку сигнатура шага допускает только String в этой второй позиции. Также не имеет смысла разрешать T там, потому что T.label уже учтено первым аргументом, а T.id относится к фактическому идентификатору элемента графа. Если вам известно это значение, вы не будете беспокоиться об указании T.label в первую очередь, поскольку T.id уже однозначно идентифицирует элемент. Вы бы просто сделали g.V(event['Id']).

person stephen mallette    schedule 03.10.2019
comment
Я не думал, что в трехзначной форме второй параметр может быть чем угодно, кроме значения ключа String. У меня тоже не получается с TinkerGraph. - person Kelvin Lawrence; 04.10.2019
comment
тьфу .... понимаете, вот почему вы не перегружаете T.id ключом свойства с именем id. просто приводит ко всякого рода недоразумениям. исправил мой ответ. спасибо Кельвин - person stephen mallette; 04.10.2019