首页 文章

Gremlin通过搜索关键字查询跨多个顶点属性的搜索

提问于
浏览
1

我正在尝试编写一个搜索查询,其中输入中是一些搜索键,并且要求在给定输入键与顶点的两个或多个属性键的值匹配的顶点之间进行搜索 . 例如,假设我的图形数据库中有用户顶点,并带有以下属性键:

  • 1)用户名

  • 2)用户姓氏

  • 3)用户电子邮件

现在给定一个搜索关键字'xyz',我必须搜索用户顶点,其中上述三个属性键中的任何一个与值'xyz'匹配 . 这就是我解决问题的方法 .

g.V.has('ENTITY_TYPE', 'USER').or(_().has('USER_EMAIL' , TEXT.REGEX , '.*xyz.*') , _().has('USER_FNAME' , TEXT.REGEX , '.*xyz.*''USER_EMAIL' , TEXT.REGEX , '.*xyz.*') , _().has('USER_LNAME' , TEXT.REGEX , '.*xyz.*')).dedup();

我为USER_EMAIL,USER_FNAME和USER_LNAME创建了所需的混合索引(三个单独的混合索引),如下所示:

key = m.makePropertyKey("USER_EMAIL").dataType(String.class).make();
m.buildIndex("serachbyemail",Vertex.class).addKey(key).buildMixedIndex("search");

key = m.makePropertyKey("USER_FNAME").dataType(String.class).make();
m.buildIndex("searchbyfname",Vertex.class).addKey(key).buildMixedIndex("search");

key = m.makePropertyKey("USER_LNAME").dataType(String.class).make();
m.buildIndex("typemixed",Vertex.class).addKey(key).buildMixedIndex("search");

这很好用 . 但我想知道这是否是解决此类问题的最佳方法?或者有更好的方法吗?另外我使用gremlin java api编写上面的查询 . 我使用dedup()来删除重复的顶点 .

1 回答

  • 2

    3个索引无助于有效地回答您的查询 . 最好创建一个覆盖所有3个字段的单个索引(这并不意味着您的查询必须具有所有字段的条件)并发出直接索引查询:

    Sample graph:

    g = TitanFactory.open("conf/titan-cassandra-es.properties")
    m = g.getManagementSystem()
    
    user = m.makeVertexLabel("USER").make()
    email = m.makePropertyKey("USER_EMAIL").dataType(String.class).make()
    fname = m.makePropertyKey("USER_FNAME").dataType(String.class).make()
    lname = m.makePropertyKey("USER_LNAME").dataType(String.class).make()
    
    m.buildIndex("users", Vertex.class).addKey(email).addKey(fname).addKey(lname).indexOnly(user).buildMixedIndex("search")
    m.commit()
    
    ElementHelper.setProperties(g.addVertexWithLabel("USER"), "USER_EMAIL", "foo@bar.com", "USER_FNAME", "foo", "USER_LNAME", "bar")
    ElementHelper.setProperties(g.addVertexWithLabel("USER"), "USER_EMAIL", "foo@xyz.com", "USER_FNAME", "foo", "USER_LNAME", "bar")
    ElementHelper.setProperties(g.addVertexWithLabel("USER"), "USER_EMAIL", "abc@bar.com", "USER_FNAME", "foo", "USER_LNAME", "xyz")
    ElementHelper.setProperties(g.addVertexWithLabel("USER"), "USER_EMAIL", "foo@baz.com", "USER_FNAME", "xyz", "USER_LNAME", "bar")
    ElementHelper.setProperties(g.addVertexWithLabel("USER"), "USER_EMAIL", "xyz@bar.com", "USER_FNAME", "xyz", "USER_LNAME", "xyz")
    
    g.commit()
    

    Direct index query:

    gremlin> g.indexQuery("users", 'v."USER_EMAIL":/.*xyz.*/ v."USER_FNAME":/.*xyz.*/ v."USER_LNAME":/.*xyz.*/').vertices()*.getElement()._().map()
    ==>{USER_FNAME=xyz, USER_LNAME=xyz, USER_EMAIL=xyz@bar.com}
    ==>{USER_FNAME=xyz, USER_LNAME=bar, USER_EMAIL=foo@baz.com}
    ==>{USER_FNAME=foo, USER_LNAME=xyz, USER_EMAIL=abc@bar.com}
    ==>{USER_FNAME=foo, USER_LNAME=bar, USER_EMAIL=foo@xyz.com}
    

    如您所见,我还用顶点标签替换了 ENTITY_TYPE . 标签可以帮助您保持索引尽可能小 . 例如,如果另一种类型的顶点(例如 PROFILE )也使用属性 USER_EMAIL ,则它不会进入索引(如果它是使用 .indexOnly(user) 创建的) .

相关问题