【问题标题】:What index is needed to answer a disjunct (__.or) query?回答分离 (__.or) 查询需要什么索引?
【发布时间】:2018-01-15 06:25:05
【问题描述】:

我想找到一组与给定搜索字符串匹配的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 索引(注释为“用户搜索”),以确保唯一性/与单个属性匹配。

索引

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

我如何重组查询和/或索引以使其正常工作?

【问题讨论】:

    标签: indexing gremlin tinkerpop janusgraph


    【解决方案1】:

    尝试使用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 之类的东西,如果您搜索多个字段,它会很方便。

    【讨论】:

    • 太好了,它有效!我花了几个小时才弄清楚索引在定义后大约需要一秒钟才能用于直接索引查询;因此,自动测试一直无法找到预期的节点。我可以建议将此作为注释添加到您的答案中吗?感谢您向我介绍此类查询。
    • 如果执行查询的索引仅限于一组顶点标签,那么只会返回带有这些标签的结果,对吧?
    • 显然是的,索引不会包含其他顶点的任何数据。
    猜你喜欢
    • 2019-05-16
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    相关资源
    最近更新 更多