Gremlin Python (AWS Neptune) получает вершины с отношениями к списку других вершин

Новое в Gremlin_python и GraphDB в целом, мы используем AWS neptune. Я пытаюсь получить список сценариев, которые имеют отношение к набору разных тегов, например. дайте мне все сценарии с тегом A и тегом B. Но набор тегов может быть динамическим (от 1 до 10 элементов).

Вопрос, как я понимаю, в термах GraphDB:

Дайте мне все вершины, от которых исходит ребро с меткой label=tag к вершинам с меткой A и B. Изображение графа

Для нединамического подхода я заставляю его работать с этим героем:

e = g.V().and_(__.out('tag').hasLabel('A'), __.out('tag').hasLabel('B')).label().toList()

Но я не могу заставить это работать со списком тегов. Я также пробовал это, но он просто генерирует оператор OR, и я не нашел способа заставить его это сделать, и:

label_list = ['A','B']
e = g.V().where(__.out('has tag').hasLabel((*label_list))).label().toList()

Я также попробовал этот подход, просто получив сообщение «Соединение было закрыто сервером», я много раз видел это с AWS Neptune, что вместо создания сообщения об ошибке закрывается соединение, а кто-нибудь знает, как это происходит ?:

label_list = ['A','B']
e = g.V().and_(map(lambda x:__.out('has tag').hasLabel(x), label_list)).label().toList()
print(len(e))

Мы тестируем это в блокноте Sage Maker, используя Python 3.8.

Итак, Интернет, не могли бы вы дать мне ответ здесь?

БР Джон

Список включенных в блокнот:

import yaml
from pathlib import Path
import json
import os

#from __future__  import print_function  # Python 2/3 compatibility

from gremlin_python import statics
from gremlin_python.structure.graph import Graph
from gremlin_python.process.graph_traversal import __
from gremlin_python.process.strategies import *
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.traversal import T
from gremlin_python.process.traversal import Order
from gremlin_python.process.traversal import Cardinality
from gremlin_python.process.traversal import Column
from gremlin_python.process.traversal import Direction
from gremlin_python.process.traversal import Operator
from gremlin_python.process.traversal import P
from gremlin_python.process.traversal import TextP
from gremlin_python.process.traversal import Pop
from gremlin_python.process.traversal import Scope
from gremlin_python.process.traversal import Barrier
from gremlin_python.process.traversal import Bindings
from gremlin_python.process.traversal import WithOptions

from argparse import ArgumentParser
from loguru import logger
import nest_asyncio
nest_asyncio.apply()
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

g.V().out('tag').hasLabel(within('A','B','C'))

ОБНОВЛЕНО: на основе комментариев.

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

g.V().where(out('tag').hasLabel(within('A','B','C')).
      label().dedup().count().is(3))

ОБНОВЛЕНО 22 февраля 2023 г.

В этом конкретном случае within на самом деле не нужен, хотя оптимизатор запросов должен генерировать один и тот же план запроса независимо. Запрос можно записать так:

g.V().where(out('tag').hasLabel('A','B','C').
      label().dedup().count().is(3))

Извините, может быть, я был неясен, я обновил пост. это должно быть "все", а не "есть". Как в логическом И между операторами, а не в ИЛИ. BR Джон

JonTheBaboon 20.02.2023 16:09

Итак, просто чтобы уточнить, у узлов есть несколько меток, таких как A::B::C , или должно быть ребро для всех типов меток с заданного начала?

Kelvin Lawrence 20.02.2023 16:18

Я обновил ответ примером, который обрабатывает последний случай.

Kelvin Lawrence 20.02.2023 16:31

Я добавил изображение с установкой, которая у меня есть. в базе данных более двух узлов сценария 1 и сценария 2. Я не понимаю команды is и inside для работы с gremlin-python и aws-neptune. Это только команды Groovy-консоли? Если я удалю внутри и есть. эта команда по-прежнему генерирует комбинацию ИЛИ.

JonTheBaboon 20.02.2023 17:21

Это стандартные слова Gremlin, НО — иногда имена шагов Gremlin конфликтуют с зарезервированными словами Python. В таких случаях вам нужно будет добавить к ним символ подчеркивания. Таким образом, is() при использовании Python становится is_(). Для within попробуйте P.within() - если ни один из них не работает, вам может потребоваться импортировать дополнительные элементы.

Kelvin Lawrence 20.02.2023 17:40
Ответ принят как подходящий

Я нашел одно решение проблемы. Больше похоже на питона, чем на Гремлина. Сгладить список кода получилось, но, возможно, есть более читаемое решение.

label_list = ['A','B']
e = g.V().and_(*[__.out('tag').hasLabel(x) for x in label_list]).label().toList()

Обновленный запрос в другом ответе по существу делает это. Удалось ли вам попробовать использовать обсуждаемые исправления для is и within?

Kelvin Lawrence 21.02.2023 01:24

если я запускаю: e = g.V().where(_.out('tag').hasLabel(P.within('A','B')).label()‌​.dedup().count( ).is_‌​(3)) e Блокнот Neptune генерирует: [['V'], ['where', [['out', 'tag'], ['hasLabel', inside(['A', ' B'])], ['label'], ['dedup'], ['count'], ['is', 3]]], ['values', '_ipython_canary_method_should_not_exist'], ['values', ' ipython_canary_method_should_not_exist']] Мне нужно прочитать, что делают используемые вами функции, чтобы понять, что пытается сделать запрос. Но то, что я хотел бы, и то, что выдает мой запрос, - это список вершин, у которых есть краевой тег для вершины A и B.

JonTheBaboon 21.02.2023 08:54

И снова, если я просто использую операторы wereinin('A','B'))), как вы предлагаете, e = g.V().where(__.out('tag').hasLabel(P.within('A','B'))). label‌​().dedup().toList() len(e) Он по-прежнему генерирует оператор ИЛИ, а не оператор И. НАПРИМЕР. список включает все вершины с ребром (с тегом метки) к вершине с меткой A ИЛИ ребро (с тегом метки) к вершине с меткой B.

JonTheBaboon 21.02.2023 10:16

Каждый вызов с использованием Python должен заканчиваться «конечным» шагом, таким как next() , iterate(), toList() и т. д. Этот конкретный вызов, вероятно, должен заканчиваться на toList(), поскольку может быть несколько результатов, и вы, вероятно, захотите их все сразу. Это часть count(), которая гарантирует, что у вас есть хотя бы один из них.

Kelvin Lawrence 21.02.2023 15:26

Да! Это сработало и сейчас. Я был на 100% уверен, что попробовал это с toList в конце. Мне просто нужно прочитать о том, как работает счет и другие шаги снижения барьера.

JonTheBaboon 21.02.2023 17:40

Есть ли мотивация для отказа от этого решения? Сегодня я провел несколько тестов функции профиля и провел около 20 тестов. время выполнения этого решения составляет от 220 до 600 мс, а решение where/inin/count/is занимает от 3300 до 6500 мс. Я попытаюсь узнать больше о выводе профиля, но я смотрю только на ключ «dur», но также вижу, что «traverserCount» и «elementCount» сильно различаются.

JonTheBaboon 22.02.2023 11:11

Интересно, что три hasLabel внутри and шага показали себя намного лучше, чем метод подсчета. Я буду исследовать это дальше. Я предполагаю, что это как-то связано с тем, что тест and может завершиться, как только он найдет один из каждого, а не считать их все.

Kelvin Lawrence 22.02.2023 18:52

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