我有一个可以拥有任意数量标题的实体。在某些情况下,每个实体有数十个甚至数百个标题。
这些标题作为数组存储在单个字段中的elasticsearch中。 该领域有一个复杂的分析器和一个复杂的标记器。
问题是弹性将数组字段(具有一组值的字段)视为单个“字符串”,并且搜索结果的相关性被计算为整个“字符串”的总相关性。但我需要的是一个特定匹配数组元素的相关性。
下面是一个非常简化的例子。
创建索引
curl -XDELETE 'http://localhost:9200/tests'
curl -XPUT 'http://localhost:9200/tests' -d'{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "edge_ngram_tokenizer",
"filter": ["lowercase", "asciifolding"]
}
},
"tokenizer": {
"edge_ngram_tokenizer": {
"type": "edgeNGram",
"min_gram": "3",
"max_gram": "12",
"token_chars": ["letter", "digit"]
}
}
}
},
"mappings": {
"test": {
"properties": {
"name": {
"type": "string",
"analyzer": "my_analyzer"
}
}
}
}
}'
填充索引
curl -XPOST 'http://localhost:9200/tests/test' -d'{ "id": 1, "name": ["text"] }'
curl -XPOST 'http://localhost:9200/tests/test' -d'{ "id": 2, "name": ["text", "text"] }'
搜索
curl -XGET 'http://localhost:9200/tests/test/_search' -d'{
"query": {
"match": {
"name": "text"
}
}
}'
结果
{
"took": 0,
"timed_out": false,
"_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 },
"hits": {
"total": 2,
"max_score": 0.7911257,
"hits": [{
"_index": "tests",
"_type": "test",
"_id": "AWOtIL2gdpqdbX7hdDXg",
"_score": 0.7911257,
"_source": { "id": 2, "name": [ "text", "text" ] }
}, {
"_index": "tests",
"_type": "test",
"_id": "AWOtIL0ldpqdbX7hdDXf",
"_score": 0.51623213,
"_source": { "id": 1, "name": [ "text" ] }
}]
}
}
正如您所见, id:2 具有相关性 0.7911257 , id:1 具有相关性 0.51623213 。
我需要两个结果具有相同的相关性。
有没有办法实现它?
我知道这个问题的两个解决方案,但两者都不适合我。也许还有其他一些选择?
a)当标题数量相对较小时,标题可以分别存储在单独的字段中:name_0,name_1,name_2等。 这些字段可以是 dis_max 请求与 tie_breaker:0 的查询,相关性也会很好。
"query": {
"dis_max": {
"queries": [
{ "match": { "name_0": "text" } },
{ "match": { "name_1": "text" } },
{ "match": { "name_2": "text" } }
],
"tie_breaker": 0,
"boost": 1
}
}
b)每个标题可以弹性存储在一个单独的行中
curl -XPOST 'http://localhost:9200/tests/test' -d'{ "product_id": 1, "name": "text" }'
curl -XPOST 'http://localhost:9200/tests/test' -d'{ "product_id": 2, "name": "text" }'
curl -XPOST 'http://localhost:9200/tests/test' -d'{ "product_id": 2, "name": "text" }'
在这种情况下,结果必须由product_id进一步汇总。因此,我们会遇到结果分页和结果进一步聚合的问题。
答案 0 :(得分:2)
我想添加到您的name
字段:
"index_options": "docs"
会做神奇的事。
此设置会告知ES不关心此字段的TF。
如果您想了解更多信息,请查看Theory in relevance。