当前位置: 首页 > 面试题库 >

跨字段搜索,每个字段中有多个完整和不完整的短语

丌官皓君
2023-03-14
问题内容

示例数据:

PUT /test/test/1
{
    "text1":"cats meow",
    "text2":"12345",
    "text3":"toy"
}

PUT /test/test/2
{
    "text1":"dog bark",
    "text2":"98765",
    "text3":"toy"
}

还有一个示例查询:

GET /test/test/_search
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "meow cats toy",
            "type" : "cross_fields"
        }
    }
}

首先返回击中的猫,然后返回狗,这就是我想要的。

但是 当您查询时cat toy,猫和狗的相关性得分相同。我希望能够考虑到该单词的前缀(并且可能在该字段中添加了其他几个单词),然后运行cross_fields

因此,如果我搜索:

GET /test/test/_search
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "cat toy",
            "type" : "phrase_prefix"
        }
    }
}

要么

GET /test/test/_search
{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "meow cats",
            "type" : "phrase_prefix"
        }
    }
}

我应该得到cat / ID 1,但没有。

我发现使用cross_fields可以实现多词短语,但不能实现多不完整的短语。并phrase_prefix获得不完整的短语,但不能获得多个不完整的短语…

筛选文档确实并没有帮助我发现如何结合这两者。


问题答案:

是的,我必须使用分析仪…

添加任何数据之前,在创建索引时将分析器应用于这些字段。添加数据后,我找不到更简单的方法来执行此操作。

我发现的解决方案是将所有短语分解成每个单独的前缀,因此cross_fields可以做到这一点。您可以在edge-ngram
此处了解有关使用的更多信息。

因此,而不是cross_field只是搜索cats短语,它现在要搜索:ccacat,和cats和每句话后......所以text1场将看起来像这样弹性:c ca cat cats m me meo meow

~~~

以下是使上述问题示例起作用的步骤:

首先,您创建并命名分析器。要了解多一点什么过滤器的值的含义,我建议你看看这个。

PUT /test
{
    "settings": {
        "number_of_shards": 1, 
        "analysis": {
            "filter": {
                "autocomplete_filter": { 
                    "type":     "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                }
            },
            "analyzer": {
                "autocomplete": {
                    "type":      "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter" 
                    ]
                }
            }
        }
    }
}

然后,我将此分析仪附加到每个字段。我更改了,text1以匹配我将其应用到的字段。

PUT /test/_mapping/test
{
    "test": {
        "properties": {
            "text1": {
                "type":     "string",
                "analyzer": "autocomplete"
            }
        }
    }
}

我跑来GET /test/_mapping确保一切正常。

然后添加数据:

POST /test/test/_bulk
{ "index": { "_id": 1 }}
{ "text1": "cats meow", "text2": "12345", "text3": "toy" }
{ "index": { "_id": 2 }}
{ "text1": "dog bark", "text2": "98765", "text3": "toy" }

和搜索!

{
    "size": 25,
    "query": {
        "multi_match" : {
            "fields" : [
                "text1", 
                "text2",
                "text3"
            ],
            "query" : "cat toy",
            "type" : "cross_fields"
        }
    }
}

哪个返回:

{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 0.70778143,
      "hits": [
         {
            "_index": "test",
            "_type": "test",
            "_id": "1",
            "_score": 0.70778143,
            "_source": {
               "text1": "cats meow",
               "text2": "12345",
               "text3": "toy"
            }
         },
         {
            "_index": "test",
            "_type": "test",
            "_id": "2",
            "_score": 0.1278426,
            "_source": {
               "text1": "dog bark",
               "text2": "98765",
               "text3": "toy"
            }
         }
      ]
   }
}

当您搜索时cat toy,这会在两者之间形成对比,而之前的分数是相同的。但是现在,这cat首热门歌曲的得分更高了。这是通过考虑每个词组的每个前缀(在这种情况下/短语中最多20个字符),然后查看数据与的相关性来实现的cross_fields



 类似资料:
  • 我有一个记录数据库,每个记录都有一个右和一个左字段,这两个字段都包含文本。数据库使用Elasticsearch建立索引。 我想搜索这些记录的两个字段,并找到在任何字段中包含两个或更多带有特定前缀的单词的记录。搜索应该足够具体,以便只查找包含查询中所有单词的记录,而不仅仅是其中的一些单词。 例如,qui bro查询应该返回包含“敏捷的棕色狐狸跳过了懒惰的狗”这句话的记录,而不是包含“敏捷的狐狸跳过了

  • 问题内容: 在elasticsearch的实现中,基于几个字段,我只有几个简单的聚合,如下所示: 聚合工作正常,我得到了相应的结果。但是返回的标题键字段(或任何其他字段-多字)具有单个字的汇总和结果。我需要返回结果中的完整标题,而不是一个单词- 没什么意义。我该怎么办。 当前结果(仅是摘录)- 预期成绩 - 我浏览了很多文档,它解释了汇总结果的不同方法,但是如果结果中的字段中有字段,我找不到如何获

  • 我有像下面这样的课。 我通过Restendpoint获取此对象。问题是,当字段passPayer和driver对象相等时,在返回的JSON中,driver字段只包含ID(它只是一个整数值),passPayer字段包含所有对象字段。 当这些字段具有不同的对象时,两个字段都显示如下所示的完整详细信息。 我需要两个对象都包含数据(字段。[id,firstName,lastName,idNo]),无论它们

  • 问题内容: 我在使用VBA执行SQL查询并将结果复制到Excel工作表时遇到问题。 子执行时,它仅复制256的倍数的行(因此,只有256、512、768等行是填充到Excel中的行)。我从数据库中复制任何其他字段都没有问题。另外,当我在MySQL中运行相同的查询时,它也可以正常工作。对于SQL和VBA来说都是相当新的东西,我看不到任何原因导致此特定字段引起麻烦。我唯一能想到的是它的内容是一个始终以

  • 问题内容: 我想基于(不是)使用新文档更新此文档。 像这样: elasticsearch版本:6.2,ES Java API:6.2 问题答案: 您基本上可以使用查询API更新来实现所需的功能,基本上是这样的: 更新:使用Java API 有关使用UpdateByQuery Java API 和Java高级Rest 客户端的更多详细信息

  • 假设我们有一个ElasticSearch实例和一个索引。我现在要在整个索引中搜索包含特定值的文档。它与在多个字段上搜索该查询相关,因此我不想指定要在其中搜索的每个字段。 到目前为止我的尝试(使用NEST)如下: 在ConnectionString上应用以下调试后,我将获得以下输出: 我该怎么做?为什么我的查询是错误的?