I want to find a set of User
vertices that match a given search string. These vertices have four String
properties to match against - FIRST_NAME
, LAST_NAME
, DISPLAY_NAME
and EMAIL
. My query is constructed like so:
Query
GraphTraversal<Vertex, Vertex> query = GraphFactory.getDefault().traversal().V()
.hasLabel(VertexLabel.USER.name())
.or( __.has(PropertyKey.EMAIL_LC.name(), Text.textRegex(regex)),
__.has(PropertyKey.DISPLAY_NAME_LC.name(), Text.textRegex(regex)),
__.has(PropertyKey.FIRST_NAME.name(), Text.textRegex(regex)),
__.has(PropertyKey.LAST_NAME.name(), Text.textRegex(regex)));
To answer it, there is one main, MIXED
index in place (commented "user search"), amongst others to ensure uniqueness / match against a single property.
Index
//Unique Email Addresses - COMPOSITE
mgmt.buildIndex("byEmailComp", Vertex.class)
.addKey(emailLowercaseKey)
.indexOnly(userLabel)
.unique()
.buildCompositeIndex();
//Unique Email Addresses - MIXED
mgmt.buildIndex("byEmailMixed", Vertex.class)
.addKey(emailLowercaseKey, Mapping.TEXTSTRING.asParameter())
.indexOnly(userLabel)
.buildMixedIndex("search");
//Unique Display Name - COMPOSITE
mgmt.buildIndex("byDisplayNameComp", Vertex.class)
.addKey(displayNameLowercaseKey)
.indexOnly(userLabel)
.unique()
.buildCompositeIndex();
//Unique Display Name - MIXED
mgmt.buildIndex("byDisplayNameMixed", Vertex.class)
.indexOnly(userLabel)
.addKey(displayNameLowercaseKey, Mapping.TEXTSTRING.asParameter())
.buildMixedIndex("search");
//User search - MIXED
mgmt.buildIndex("userSearch", Vertex.class)
.indexOnly(userLabel)
.addKey(displayNameLowercaseKey, Mapping.TEXTSTRING.asParameter())
.addKey(emailLowercaseKey, Mapping.TEXTSTRING.asParameter())
.addKey(firstNameKey, Mapping.TEXTSTRING.asParameter())
.addKey(lastNameKey, Mapping.TEXTSTRING.asParameter())
.buildMixedIndex("search");
When running the query, an exception is thrown.
Query needs suitable index to be answered [(~label = USER)]:VERTEX
However, if I match against a property at a time, no exception is thrown. Like so:
GraphFactory.getDefault().traversal().V()
.hasLabel(VertexLabel.USER.name())
.has(PropertyKey.EMAIL_LC.name(), Text.textRegex(regex));
// or
GraphFactory.getDefault().traversal().V()
.hasLabel(VertexLabel.USER.name())
.has(PropertyKey.DISPLAY_NAME_LC.name(), Text.textRegex(regex));
// or...
How could I restructure the query and/or index for this to work?