Я собираю запросы программно во время выполнения, и предложение match является более общим способом решения этой задачи. Большинство из них работают нормально, но некоторые в какой-то момент возвращают исключение «Неразрешимый шаблон».
Я проверил здесь как единственный подобный вопрос на SO, но он не отвечает и не объясняет проблему, по крайней мере для меня.
Вот моя неудачная попытка.
g.V().match(
__.as('loc').has('guid','EGLD').out('instanceOfSupClass').hasLabel('Main_Location'),
__.as('meter1').out('instanceOfSupClass').hasLabel('Electricity_Meter'),
__.as('meter2').out('instanceOfSupClass').hasLabel('Electricity_Meter'),
__.as('class').out('instanceOfSupClass').hasLabel('Cleaned_Electricty_Meter'),
__.as('meter1').out('hasLocation').as('loc'),
__.as('meter2').out('isPartOf').as('meter1'),
__.as('meter2').out('hasTimeSeries').as('class')
)
с ужасом:
Exception in thread "main" java.lang.IllegalStateException: The provided match pattern is unsolvable: [[MatchStartStep(_m), VertexStep(OUT,[is],vertex), HasStep([~label.eq(A)]), MatchEndStep], [MatchStartStep(_m2), VertexStep(OUT,[bar],edge), StoreStep(edges), EdgeVertexStep(IN), MatchEndStep(_m1)], [MatchStartStep(_m1), VertexStep(OUT,[foo],edge), StoreStep(edges), EdgeVertexStep(IN), MatchEndStep(_l)], [MatchStartStep(c), VertexStep(OUT,[is],vertex), HasStep([~label.eq(D)]), MatchEndStep], [MatchStartStep(_m1), VertexStep(OUT,[is],vertex), HasStep([~label.eq(B)]), MatchEndStep], [MatchStartStep(_l), VertexStep(OUT,[is],vertex), HasStep([~label.eq(A)]), MatchEndStep], [MatchStartStep(_m1), VertexStep(OUT,[beer],edge), StoreStep(edges), EdgeVertexStep(IN), MatchEndStep(c)]]
Теперь вот похожий, который работает вместо:
g.V().match(
__.as('loc').has('guid','EGLD').out('instanceOfSupClass').hasLabel('Main_Location'),
__.as('meter1').out('instanceOfSupClass').hasLabel('Electricity_Meter'),
__.as('meter2').out('instanceOfSupClass').hasLabel('Electricity_Meter'),
__.as('class').out('instanceOfSupClass').hasLabel('Cleaned_Electricty_Meter'),
__.as('meter1').out('hasLocation').as('loc'),
__.as('meter2').out('isPartOf').as('meter1'),
__.as('meter1').out('hasTimeSeries').as('class')
)
Я бы ожидал, что они оба дадут один результат (хотя и разные, так как они разные).
Я бы хотел понять, почему это происходит с ошибкой и, в конце концов, если это ошибка или я что-то упустил.
EDIT:
добавить примеры и параллелизмы между игрушечным графом (который не выдает ошибку) и моими реальными запросами (я не могу загрузить пример моего графика)
beer_graph=TinkerGraph.open()
g = beer_graph.traversal()
A = g.addV('A').next()
B = g.addV('B').next()
C = g.addV('C').next()
LOK = g.addV().next()
MOK1 = g.addV().next()
MOK2 = g.addV().next()
COK = g.addV().next()
g.V(LOK).addE('is').to(A)
g.V(MOK1).addE('is').to(B)
g.V(MOK2).addE('is').to(B)
g.V(COK).addE('is').to(C)
g.V(MOK1).addE('foo').to(LOK)
g.V(MOK2).addE('bar').to(MOK1)
g.V(MOK2).addE('beer').to(COK)
LKO = g.addV().property('guid', 'LKO').next()
MKO1 = g.addV().next()
MKO2 = g.addV().next()
CKO = g.addV().next()
g.V(LKO).addE('is').to(A)
g.V(MKO1).addE('is').to(B)
g.V(MKO2).addE('is').to(B)
g.V(CKO).addE('is').to(C)
g.V(MKO1).addE('foo').to(LKO)
g.V(MKO2).addE('bar').to(MKO1)
g.V(MKO1).addE('beer').to(CKO)
g.V().match(
__.as('_l').has('guid', 'LKO').outE('is').inV().hasLabel('A'),
__.as('_m1').outE('is').inV().hasLabel('B'),
__.as('_m2').outE('is').inV().hasLabel('B'),
__.as('_c').outE('is').inV().hasLabel('C'),
__.as('_m1').outE('foo').inV().as('_l'),
__.as('_m2').outE('bar').inV().as('_m1'),
__.as('_m1').outE('beer').inV().as('_c')
)
g.V().match(
__.as('_l').outE('is').inV().hasLabel('A'),
__.as('_m1').outE('is').inV().hasLabel('B'),
__.as('_m2').outE('is').inV().hasLabel('B'),
__.as('_c').outE('is').inV().hasLabel('C'),
__.as('_m1').outE('foo').inV().as('_l'),
__.as('_m2').outE('bar').inV().as('_m1'),
__.as('_m2').outE('beer').inV().as('_c')
)
Оба работают и возвращают правильно результат. Теперь, отойдя от игрушечного графа, это мой обход во время выполнения моего проекта:
g.V().match(
__.as('loc').has('guid','EGLD').out('instanceOfSupClass').hasLabel('Main_Location'),
__.as('meter1').out('instanceOfSupClass').hasLabel('Electricity_Meter'),
__.as('meter2').out('instanceOfSupClass').hasLabel('Electricity_Meter'),
__.as('class').out('instanceOfSupClass').hasLabel('Cleaned_Electricty_Meter'),
__.as('meter1').out('hasLocation').as('loc'),
__.as('meter2').out('isPartOf').as('meter1'),
__.as('meter2').out('hasTimeSeries').as('class')
)
[
[MatchStartStep(loc), HasStep([guid.eq(EGLD)]), VertexStep(OUT,[instanceOfSupClass],vertex), HasStep([~label.eq(Main_Location)]), MatchEndStep],
[MatchStartStep(meter1), VertexStep(OUT,[instanceOfSupClass],vertex), HasStep([~label.eq(Electricity_Meter)]), MatchEndStep],
[MatchStartStep(meter2), VertexStep(OUT,[instanceOfSupClass],vertex), HasStep([~label.eq(Electricity_Meter)]), MatchEndStep],
[MatchStartStep(class), VertexStep(OUT,[instanceOfSupClass],vertex), HasStep([~label.eq(Cleaned_Electricty_Meter)]), MatchEndStep],
[MatchStartStep(meter1), VertexStep(OUT,[hasLocation],vertex), MatchEndStep(loc)],
[MatchStartStep(meter2), VertexStep(OUT,[isPartOf],vertex), MatchEndStep(meter1)],
[MatchStartStep(meter2), VertexStep(OUT,[hasTimeSeries],vertex), MatchEndStep(class)]
]
По сравнению с скомпилированным предыдущим
g.V().match(
__.as('_l').has('guid', 'LKO').outE('is').inV().hasLabel('A'),
__.as('_m1').outE('is').inV().hasLabel('B'),
__.as('_m2').outE('is').inV().hasLabel('B'),
__.as('_c').outE('is').inV().hasLabel('C'),
__.as('_m1').outE('foo').inV().as('_l'),
__.as('_m2').outE('bar').inV().as('_m1'),
__.as('_m1').outE('beer').inV().as('_c')
)
[
[MatchStartStep(_l), HasStep([guid.eq(LKO)]), VertexStep(OUT,[is],vertex), HasStep([~label.eq(A)]), MatchEndStep],
[MatchStartStep(_m1), VertexStep(OUT,[is],vertex), HasStep([~label.eq(B)]), MatchEndStep],
[MatchStartStep(_m2), VertexStep(OUT,[is],vertex), HasStep([~label.eq(B)]), MatchEndStep],
[MatchStartStep(_c), VertexStep(OUT,[is],vertex), HasStep([~label.eq(C)]), MatchEndStep],
[MatchStartStep(_m1), VertexStep(OUT,[foo],vertex), MatchEndStep(_l)],
[MatchStartStep(_m2), VertexStep(OUT,[bar],vertex), MatchEndStep(_m1)],
[MatchStartStep(_m1), VertexStep(OUT,[beer],vertex), MatchEndStep(_c)]
]
Почему исключение "неразрешимый шаблон" и почему изменение графика имеет значение? Если на текущем графике шаблон «неразрешим», я ожидаю пустой результат, а не исключение ...
РЕДАКТИРОВАТЬ 2: обнаружил разницу, не понимая проблемы
Мне удалось восстановить "инкриминированный" сценарий, этот НЕ РАБОТАЕТ ...
g.V().match(
__.as("_loc").has("guid","EGLD").out("instanceOfSupClass").hasLabel("Main_Location"),
__.as("_meter1").out("instanceOfSupClass").hasLabel("Electricity_Meter"),
__.as("_meter1").outE("hasLocation").store("edges").inV().as("_loc"),
__.as("_meter1").outE("hasTimeSeries").store("edges").inV().as("class"),
__.as("_meter2").out("instanceOfSupClass").hasLabel("Electricity_Meter"),
__.as("_meter2").outE("isPartOf").store("edges").inV().as("_meter1"),
__.as("class").out("instanceOfSupClass").hasLabel("Virtual_Anomaly_Class_Time_Series")
)
Этот работает ...
g.V().match(
__.as("_meter2").out("instanceOfSupClass").hasLabel("Electricity_Meter"),
__.as("_meter2").outE("isPartOf").store("edges").inV().as("_meter1"),
__.as("_meter1").outE("hasLocation").store("edges").inV().as("_loc"),
__.as("_meter1").out("instanceOfSupClass").hasLabel("Electricity_Meter"),
__.as("class").out("instanceOfSupClass").hasLabel("Virtual_Anomaly_Class_Time_Series"),
__.as("_loc").has("guid","EGLD").out("instanceOfSupClass").hasLabel("Main_Location"),
__.as("_meter1").outE("hasTimeSeries").store("edges").inV().as("class")
)
ТАК ЗАКАЗЫ