一尘不染

在Elasticsearch中查找最相似的整数数组

elasticsearch

改写:

在我的项目中,我有图像。每个图像有5个标签,范围为[1,10]。我用Elasticsearch上传了这些标签:

我将这些文件加载​​到类型为“ img”的索引“ my_project”中的elasticsearch中:

curl -XPUT 'http://localhost:9200/my_project/img/1' -d '
 {"tags": [1,4,6,7,9]}
'

我上传的其他示例文件:

{"tags": [1,4,6,7]}
{"tags": [2,3,5,6]}
{"tags": [1,2,3,8]}

在我的应用程序中,向量要长得多,但是具有固定数量的唯一元素。我喜欢这些文件中的20M。

现在,我想找到给定向量的相似文档。向量具有更多公共标签时,它们会更加相似。因此,例如,我想为整数向量查找最相似的文档[1,2,3,7]。最佳匹配应该是最后一个示例文档{"tags": [1,2,3,8]},因为它们在其标签中共享3个公共值,这些[1,2,3]公共值比其他任何向量都多。

所以这是我的问题。如果使用上述CURL命令上传文档,则会得到以下映射:

{
  "my_project" : {
    "mappings" : {
      "img" : {
        "properties" : {
          "tags" : {
            "type" : "string"
          }
        }
      }
    }
  }
}

但是我认为正确的映射应该使用整数而不是字符串。如何为此类数据进行正确的显式映射?

现在,我想使用上述相似度算法搜索文档。如何使用上述相似性算法获得100个上述类型的最相似文档?如果我将这些向量转换为以空格分隔的数字的字符串,则可以将布尔查询与应当声明一起使用于此搜索,但我认为使用整数数组应该更快。您能告诉我,如何为Elasticsearch构建该搜索查询?


到目前为止我的解决方案

我现在使用的基本解决方案是将整数数组转换为字符串。所以我将文档另存为:

curl -XPUT 'http://localhost:9200/my_project/img/1' -d '
 {"tags": "1 4 6 7 9"}
'

然后基本上搜索string "1 2 3"。虽然这可以某种方式起作用,但我认为将整数数组保存为整数数组而不是字符串会更正确,更快捷。是否可以像在整数搜索数组中一样在elasticsearch中使用整数数组?也许我使用字符串的方法是最好的,并且可以/不必在elasticsearch中显式使用整数数组。


阅读 409

收藏
2020-06-22

共1个答案

一尘不染

我将在去年的Elasticsearch邮件列表中查看去年的讨论。另一个ES用户正在尝试完全按照您的意图进行操作,匹配数组元素并按相似性进行排序。在他的情况下,他的数组成员是“一个”,“两个”,“三个”等,但几乎相同:

http://elasticsearch-users.115913.n3.nabble.com/Similarity-score-in-array-
td4041674.html

讨论中指出的问题是,没有什么可以让您准确地找到想要的东西。您使用数组成员(字符串或整数,我认为都可以)的方法可以使您接近,但可能与您要实现的目标有所不同。原因是Elasticsearch(以及Lucene
/ Solr也是如此)中的默认相似性评分机制是TF /
IDF:http :
//www.elasticsearch.org/guide/en/elasticsearch/guide/current/relevance-
intro.html

TF / IDF可能非常接近,并且取决于用例,可能会为您提供相同的结果,但不能保证做到这一点。经常出现的标签(例如,“ 1”的频率是“
2”的两倍)会更改每个术语的权重,以致您可能无法完全获得所需的内容。

如果您需要精确的评分/相似度算法,我相信您需要自定义评分。正如您发现的那样,自定义评分脚本无法很好地扩展,因为该脚本将在每个文档中运行,因此开始时并不太快,并且响应时间会以线性方式衰减。

我个人可能会尝试Elasticsearch提供的某些相似性模块,例如BM25:

http://www.elasticsearch.org/guide/zh-
CN/elasticsearch/reference/current/index-modules-
similarity.html

2020-06-22