回答分离 (__.or) 查询需要什么索引?

What index is needed to answer a disjunct (__.or) query?

我想找到一组 User 个与给定搜索字符串匹配的顶点。这些顶点有四个 String 属性来匹配 - FIRST_NAMELAST_NAMEDISPLAY_NAMEEMAIL。我的查询是这样构造的:

查询

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)));

为了回答这个问题,有一个主要的 MIXED 索引(评论 "user search"),除其他外,以确保唯一性/匹配单个 属性.

索引

//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");

当运行查询时,抛出异常

Query needs suitable index to be answered [(~label = USER)]:VERTEX

但是,如果我一次匹配 属性,则不会抛出异常。像这样:

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...

我如何重组查询 and/or 索引才能使其正常工作?

尝试使用 direct index query:

final String searchTerm =
    "v." + PropertyKey.EMAIL_LC.name() + ":(" + regex + ") OR " +
    "v." + PropertyKey.DISPLAY_NAME_LC.name() + ":(" + regex + ") OR " +
    "v." + PropertyKey.FIRST_NAME.name() + ":(" + regex + ") OR " +
    "v." + PropertyKey.LAST_NAME.name() + ":(" + regex + ")";

GraphFactory.getDefault().indexQuery("userSearch", searchTerm).vertices()

直接索引查询的好处在于,您还可以使用 query boosting 之类的东西,如果您搜索多个字段,它会派上用场。