假设我的索引有两个文档:
- “拿我的钱”
- “我的钱到了”
当我对“get my money”进行常规匹配查询时,两个文档都正确匹配,但得分相同。但是,我希望在评分过程中单词的顺序很重要。换句话说,我希望“得到我的钱”有更高的分数。
因此,我尝试将匹配查询放在 bool 查询的 must 子句中,并包含一个 match_phrase(具有相同的查询字符串)。在我用“我如何得到我的钱”进行搜索之前,这似乎正确地得分。在这种情况下,match_phrase 查询似乎不匹配,并且再次以相同的分数返回命中。
如何构建我的索引/查询,以便考虑词序但不要求所有搜索的词都存在于文档中?
与测试数据的索引映射
PUT test-index
{
"mappings": {
"properties" : {
"keyword" : {
"type" : "text",
"similarity": "boolean"
}
}
}
}
POST test-index/_doc/
{
"keyword" : "get my money"
}
POST test-index/_doc/
{
"keyword" : "my money get here"
}
查询“我如何获得我的钱” - 没有按需要工作
GET /test-index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"keyword": "how do i get my money"
}
}
],
"should": [
{
"match_phrase": {
"keyword": {
"query": "how do i get my money"
}
}
}
]
}
}
}
结果(两份文件得分相同)
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 3.0,
"hits" : [
{
"_index" : "test-index",
"_type" : "_doc",
"_id" : "6Xy8wXIB3NtI_ttPGBoV",
"_score" : 3.0,
"_source" : {
"keyword" : "get my money"
}
},
{
"_index" : "test-index",
"_type" : "_doc",
"_id" : "6ny8wXIB3NtI_ttPGBpV",
"_score" : 3.0,
"_source" : {
"keyword" : "my money get here"
}
}
]
}
}
编辑 1
正如@gibbs 建议的那样,让我们删除"similarity": "boolean"
. 下面介绍了一个更加简化和集中的问题。我们正在努力寻找这个问题的答案。
已移除
"similarity": "boolean"
PUT test-index
{
"mappings": {
"properties" : {
"keyword" : {
"type" : "text"
}
}
}
}
POST test-index/_doc/
{
"keyword": "get my money"
}
POST test-index/_doc/
{
"keyword": "my money get here"
}
如何使这个查询返回结果?现在没有了。使用时如果文档中不存在所有搜索词,是否可以返回结果match_phrase
?
GET /test-index/_search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"keyword": {
"query": "how do I get my money"
}
}
}
]
}
}
}
编辑 2
在我们的用例中,我们不能使用 BM25 (TF/IDF),因为这会破坏我们的结果。
POST test-index/_doc
{
"keyword": "get my money, claim, distribution, getting started"
}
POST test-index/_doc
{
"keyword": "my money get here"
}
GET /test-index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"keyword": "how do I get my money"
}
}
]
}
}
}
结果
{
"took" : 16,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.6156533,
"hits" : [
{
"_index" : "test-index",
"_type" : "_doc",
"_id" : "JnxCw3IB3NtI_ttPBjQv",
"_score" : 0.6156533,
"_source" : {
"keyword" : "my money get here"
}
},
{
"_index" : "test-index",
"_type" : "_doc",
"_id" : "x3xSw3IB3NtI_ttP1DUi",
"_score" : 0.49206492,
"_source" : {
"keyword" : "get my money, claim, distribution, getting started"
}
}
]
}
}
在这种情况下,由于 TF/IDF,我的钱得到的分数比预期的要高。所以,我们不能让分数计算取决于匹配的文档数量、字段长度等。
对不起,很长的问题。那么,回到我原来的问题,如何构建我的索引/查询,以便考虑词序但不要求所有搜索的词都存在于文档中?