通过跨多个顶点属性的搜索键进行 Gremlin 查询搜索
Gremlin query search by search key across multiple vertex properties
我正在尝试编写一个搜索查询,其中输入是一些搜索键,要求是在给定输入键与两个或多个 属性 键的值匹配的顶点之间进行搜索顶点。例如,假设我的图形数据库中有用户顶点,具有以下 属性 键:
- 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() 删除重复的顶点。
这 3 个索引无助于有效地回答您的查询。最好创建一个涵盖所有 3 个字段的索引(这并不意味着您的查询必须对所有字段都有条件)并发出直接索引查询:
示例图:
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()
直接索引查询:
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
,它不会进入索引(如果它是使用 [=15= 创建的) ]).
我正在尝试编写一个搜索查询,其中输入是一些搜索键,要求是在给定输入键与两个或多个 属性 键的值匹配的顶点之间进行搜索顶点。例如,假设我的图形数据库中有用户顶点,具有以下 属性 键:
- 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() 删除重复的顶点。
这 3 个索引无助于有效地回答您的查询。最好创建一个涵盖所有 3 个字段的索引(这并不意味着您的查询必须对所有字段都有条件)并发出直接索引查询:
示例图:
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()
直接索引查询:
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
,它不会进入索引(如果它是使用 [=15= 创建的) ]).