查询
redisearch的查询用到的是friso分词方法,对于这种分词引擎相较与ik粒度更粗,功能也更单一,
我们主要看一下rediseach在全文检索时存在哪些需要改进的地方。
先看下面文档
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新文档中不存在的内容将被留。对于的与和两者中间隔超过60个字符将不做任何处理"
该文档在创建时已经指定了语言为chinese也就是说中文分词器是起作用的。
这时我们执行查询“新文档”竟然没有查询到任何结果,这显然与我们的期望和猜想大相径庭。
ft.search student "新文档*"
1) "0"
而当我们单独查询“新” 、 “文档”都是可以查询出结果即使不加模糊匹配符号,这究竟时什么原因照成的?
ft.search student "新"
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新文档中不存在的内容将被留。对于的与和两者中间隔超过60个字符将不做任何处理"
ft.search student "文档"
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新文档中不存在的内容将被留。对于的与和两者中间隔超过60个字符将不做任何处理"
其实是rediseach分词器将“新文档”分解成了“新”和“文档”,但即便如此按道理来书我们查询“新文档”也不能不给我们反馈结果吧,这就是redisearch的不足之处,因为这样照成的结果就是模糊匹配只能按照redisearch的分词思想来进行关键词的查询,而处理不了多个关键词(或者说是分词)组成的短语,这的确是个坑,
既然有问题我们就要考虑有没有什么办法解决这种问题。
对于底层设计我们是很难去修改的,那有没有一种比较巧妙的方法解决这个问题那,答案是有的,但依然不要太兴奋因为至今我没有找到很完美的办法。
既然它分词那么我们也分词看下面的查询
ft.search student "新,文档"
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新文档中不存在的内容将被留。对于的与和两者中间隔超过60个字符将不做任何处理"
经过我们手动分词数据成功查询出来了,也许你很聪明的想到问题已经解决了,我只要在查询的时候手动调用一下分词器,用分词器返回的结果作为条件进行查询不就完美了,说实话如果对数据检索结果要求不是很高的情况下绝对是没问题的,但是如果要生成报表或统计就无法确保数据准确性了,
ft.search student "中,间隔"
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新文档中不存在的内容将被留。对于的与和两者中间隔超过60个字符将不做任何处理"
我们查"中间隔"我们查“中,间隔”可以查到数据但如果查“中间,隔”
ft.search student "中间,隔"
1) "0"
竟然没有查到数据,而且我们很容易猜到原因,很不幸的正是由于没有了上下文的语境分词器会把它真的分词为“中间”和“隔”
那么既然查询的时候可以手动分词存储的时候一定也能分词了,我们手动给他分成“–两者,中,间隔–”,的确可以这样做,但这样坏处也是很显然的,那索性全都分开
ft.search student *
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新 文 档 中 不 存 在 的 内 容 将 被 留 。对 于 的 与 和 两 者 中 间 隔 超 过 60 个 字 符 将 不 做 任 何 处 理"
请注意body字段中的文字以空格隔开,(空格和逗号都有分词的意思)
ft.search student "中,间,隔"
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新 文 档 中 不 存 在 的 内 容 将 被 留 。对 于 的 与 和 两 者 中 间 隔 超 过 60 个 字 符 将 不 做 任 何 处 理"
不仅可以这样查你还可以这样查
ft.search student "隔,间,中"
1) "1"
2) "doc0"
3) 1) "title"
2) "任何视频"
3) "star"
4) "1000"
5) "body"
6) "新 文 档 中 不 存 在 的 内 容 将 被 留 。对 于 的 与 和 两 者 中 间 隔 超 过 60 个 字 符 将 不 做 任 何 处 理"
其实挺无语这样每一个字都建了索引,只要你的文档中包含你要搜索的条件的字符都会被检索出来,相较与上面的分词方式来说性能一定是差很多,而且搜索出的无用文档也会很多。
查询结语
全文检索中需要更多的结果还是更准确的结果,我想更多的时候需要根据业务来定,但就目前而言rediseach这个组件相较于es solr等全文搜索引擎还有很大的不成熟之处。新技术都是需要慢慢磨练慢慢完善,结构化数据库的like虽然慢但它是准确的,全文收索虽然快准确性却又难以保证,存在即合理,不能说哪个好哪个不好,主要还是看我们怎么用,如何化腐朽为神奇,当然我们也希望技术本身是完备的,我们希望拿来即用,而不是关注技术本身的细枝末节。