做舆情系统,爬虫采集了很多文章,这些文章都保存在了ES上,当用户看到一篇文章的时候,需要将这篇文章的相似文章都找出来。ES的底层是一个搜索引擎,查找相似文章没问题,不过文章都比较长,直接基于整个文章去计算相似性,恐怕不太妙。
于是我们想到了搜索引擎常用的相似性算法simhash,这是Google在07年提出的算法,算法思想这个文章讲得比较透彻了:https://zhuanlan.zhihu.com/p/81026564

来自知乎
有了simhash算法,我们就能讲一篇常常的文章变成一个64位的二进制字符串,ES好像是在7.2版本之后,可以直接支持向量计算,如果放到现在就简单了。不过我们用的那个时候,版本还在6,没有向量计算功能。
将向量转化为搜索特征
es那个时候虽然还不支持向量,但是支持关键词搜索,我们只要使用空格将特征分开,然后就能搜索。而simhash是要计算相同位上相同值的个数,相同的值越多,相似度越高。我们的算法大概如下:
假设,有个文章对应的simhash为“1011”(一个二进制位表示两个状态,64位共有128个状态):
例如一个文章的simhash值为:
1011100101010111000100111010011110110010100111101000100001110111
转换成搜索特征为:
1 2 5 7 9 10 12 15 16 19 20 23 24 27 29 31 32 34 36 39 40 42 45 47
49 50 53 54 56 59 61 63 65 66 69 71 72 74 77 78 81 82 84 87 89 91
93 94 97 98 100 102 105 106 108 110 112 115 117 119 120 123 125 127需要计算某个文章的相似文章数量的时候,需要做的是:先按上面的算法生成自己的搜索特征,然后根据搜索特征去ES搜索,返回匹配的若干条个文章(例如该值设置为500,那大于该值的则可以显示为500+,搜索时可以设置匹配度),然后再对结果做一次相似度计算(最简单的,对两个搜索特征做交集运算即可)
这就是在ES尚未支持向量计算的年代讨巧的实现方式。不过虽然实现有点讨巧,不过这整个思路还是很值得学习的。