命名规则
全文索引由开发者自定义名称,一个图集中的全文索引不能重名。
- 2 ~ 64 个字符
- 必须以字母开头
- 仅允许使用字母,下划线和数字(即 _ 、A-Z、a-z、0-9)
查看全文索引
返回的表名:_nodeFulltext
、_edgeFulltext
返回的表头:name
|properties
|schema
|status
(全文索引的名称、参照属性、所属 schema、当前状态 [creating|done])
语法:
// 查看当前图集中的所有全文索引(分为点、边两个表)
show().fulltext()
// 查看当前图集中的所有全文点索引
show().node_fulltext()
// 查看当前图集中的所有全文边索引
show().edge_fulltext()
创建全文索引
语法:
// 在当前图集中为某个 点schema 的某个属性创建全文索引
create().node_fulltext(@<schema>.<property>,"<name>")
// 在当前图集中为某个 边schema 的某个属性创建全文索引
create().edge_fulltext(@<schema>.<property>,"<name>")
示例:为商品 @product 的商品描述 description 创建全文索引,命名为 prodDesc
create().node_fulltext(@product.description, "prodDesc")
删除全文索引
语法:
// 从当前图集中删除某个点属性的全文索引
drop().node_fulltext("<name>")
// 从当前图集中删除某个边属性的全文索引
drop().edge_fulltext("<name>")
示例:删除名为 prodDesc 的全文索引
drop().node_fulltext("prodDesc")
全文过滤
全文过滤是为了实现 Ultipa 高速全文搜索,对 Ultipa 过滤进行的扩展。全文过滤使用专属的条件操作符 contains
来判断一个全文索引内容的分词结果中是否包含了所有给定的关键字。“包含”的判断标准分两种:
- 精确匹配:
- 分词与关键字完全相等
- 可能会因分词库中不含被搜索关键字而导致匹配无结果
- 模糊匹配:
- 分词以关键字开头
- 能最大程度地匹配到可能包含被搜索关键字的点、边(的属性),但是返回时间比精确匹配更长
建议尽可能使用模糊匹配,除非用户有明确的精确匹配的诉求,但如果是这样,为什么还要使用全文搜索呢?
语法:{~<fulltext> contains "<keyword1> <keyword2> ..."}
其中,多个 <keyword>
用空格隔开,<keyword>
内有英文双引号时需在前面加反斜杠 \
;用于模糊匹配的 <keyword>
须以星号 *
结尾。
应用:点、边查询
示例:通过全文索引 prodDesc 查找含有关键字“保本”和“高收益”的商品
find().nodes({~prodDesc contains "保本 高收益"}) return nodes
示例:通过全文索引 prodDesc 查找含有关键字“保本”或“高收益”的商品
find().nodes({~prodDesc contains "保本" || ~prodDesc contains "高收益"}) return nodes
示例:通过全文索引 prodDesc 搜索含有“graph”和以“ult”开头的词的商品
find().nodes({~prodDesc contains "graph ult*"}) return nodes
应用:模板查询
示例:查询 10 条从 ~companyName 中有分词“资本*”的账户出发,先到达有分词“投资*”的账户,再到达有分词“人工智能*”的账户的路径
n({~companyName contains "资本*"}).e().n({~companyName contains "投资*"})
.e().n({~companyName contains "人工智能*"}) as paths
return paths{*} limit 10
示例:查询 10 条从 ~companyName 中有分词“红杉*”的账户出发,5 步之内到达有分词“高瓴*”的账户的路径
n({~companyName contains "红杉*"}).e()[:5].n({~companyName contains "高瓴*"}) as paths
return paths{*} limit 10
注:在一张 GP/LP 或工商类的知识图谱网络中,上面的查询条件相当于把“红杉”与“高瓴”的多家公司做了一个深度的自组网。同样的操作无论是人工还是在三查的系统中,都需要大量的手工干预或批处理执行,无法做到像 Ultipa 一样,通过一个简单的 UQL 语句就能实时实现的。