search for vertices where multiple properties

I need to search for vertices where multiple properties are a certain value. Here is what I am able to come up with.
try (TinkerGraph graph = TinkerGraph.open()) {
Vertex person1 = graph.addVertex(T.label, "Person", "name", "John", "surname", "Smith", "id", 1);
Vertex person2 = graph.addVertex(T.label, "Person", "name", "John", "surname", "Do", "id", 2);
Vertex person3 = graph.addVertex(T.label, "Person", "name", "John", "surname", "Ho", "id", 3);
Vertex person4 = graph.addVertex(T.label, "Person", "name", "Jo", "surname", "Do", "id", 4);

List<Vertex> persons = graph.traversal().V().hasLabel("Person")
.has("name", P.within("John", "Jo"))
.has("surname", P.within("Smith", "Do"))
.toList();

System.out.println(persons.stream().map(v -> "[" + v.value("name") + " " + v.value("surname") + "]").reduce((a,b) -> a + "," + b).orElse(""));

persons = graph.traversal().V().hasLabel("Person").as("person")
.values("name").concat(__.select("person").values("surname"))
.filter(t -> Arrays.asList("JohnSmith", "JoDo").contains(t.get()))
.<Vertex>select("person")
.toList();
System.out.println(persons.stream().map(v -> "[" + v.value("name") + " " + v.value("surname") + "]").reduce((a,b) -> a + "," + b).orElse(""));
}
try (TinkerGraph graph = TinkerGraph.open()) {
Vertex person1 = graph.addVertex(T.label, "Person", "name", "John", "surname", "Smith", "id", 1);
Vertex person2 = graph.addVertex(T.label, "Person", "name", "John", "surname", "Do", "id", 2);
Vertex person3 = graph.addVertex(T.label, "Person", "name", "John", "surname", "Ho", "id", 3);
Vertex person4 = graph.addVertex(T.label, "Person", "name", "Jo", "surname", "Do", "id", 4);

List<Vertex> persons = graph.traversal().V().hasLabel("Person")
.has("name", P.within("John", "Jo"))
.has("surname", P.within("Smith", "Do"))
.toList();

System.out.println(persons.stream().map(v -> "[" + v.value("name") + " " + v.value("surname") + "]").reduce((a,b) -> a + "," + b).orElse(""));

persons = graph.traversal().V().hasLabel("Person").as("person")
.values("name").concat(__.select("person").values("surname"))
.filter(t -> Arrays.asList("JohnSmith", "JoDo").contains(t.get()))
.<Vertex>select("person")
.toList();
System.out.println(persons.stream().map(v -> "[" + v.value("name") + " " + v.value("surname") + "]").reduce((a,b) -> a + "," + b).orElse(""));
}
This will print out,
[John Smith],[John Do],[Jo Do]
[John Smith],[Jo Do]
[John Smith],[John Do],[Jo Do]
[John Smith],[Jo Do]
The second query is the results I am looking for, but is there a better way to do this? Using concat and filter is hard to optimize.
4 Replies
Valentyn Kahamlyk
it can be done with or graph.traversal().V().hasLabel("Person"). where(or(has("name", "John").has("surname", "Smith"), has("name", "Jo").has("surname","Do"))). toList()
pieter
pieterOP13mo ago
Ah thanks, that is a better query. Thinking a bit more this one however is a little hard coded in the sense that it does not take a collection of sorts. Some kind of specialized P.within In my current use case there are thousands of name, surname pairs to filter on.
Valentyn Kahamlyk
if such filtering is needed often, then a possible solution would be to add a field containing both first and last name
pieter
pieterOP13mo ago
Yes, however I am more interested in a general solution. Something like this maybe?
List<Vertex> persons = this.sqlgGraph.traversal().V().hasLabel("Person")
.has(
P.within(
List.of("John", "Junior", "Smith"),
List.of("John", "Senior", "Do"),
List.of("Jo", "Other", "Do")
),
"name", "middlename", "surname"
)
.toList();
List<Vertex> persons = this.sqlgGraph.traversal().V().hasLabel("Person")
.has(
P.within(
List.of("John", "Junior", "Smith"),
List.of("John", "Senior", "Do"),
List.of("Jo", "Other", "Do")
),
"name", "middlename", "surname"
)
.toList();
This messes with the has signature, but gives the idea.
Want results from more Discord servers?
Add your server