elasticsearch 查询(match和term)

本文深入探讨了Elasticsearch中match、term查询及多字段匹配的方法,包括match、match_phrase、multi_match等查询类型的应用与参数调整技巧,以及term查询在未被分析字段的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

elasticsearch 查询(match和term)

es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL)。
由于DSL查询更为直观也更为简易,所以大都使用这种方式。
DSL查询是POST过去一个json,由于post的请求是json格式的,所以存在很多灵活性,也有很多形式。
这里有一个地方注意的是官方文档里面给的例子的json结构只是一部分,并不是可以直接黏贴复制进去使用的。一般要在外面加个query为key的机构。

match

最简单的一个match例子:

查询和"我的宝马多少马力"这个查询语句匹配的文档。

{
  "query": {
    "match": {
        "content" : {
            "query" : "我的宝马多少马力"
        }
    }
  }
}

上面的查询匹配就会进行分词,比如"宝马多少马力"会被分词为"宝马 多少 马力", 所有有关"宝马 多少 马力", 那么所有包含这三个词中的一个或多个的文档就会被搜索出来。
并且根据lucene的评分机制(TF/IDF)来进行评分。

match_phrase

比如上面一个例子,一个文档"我的保时捷马力不错"也会被搜索出来,那么想要精确匹配所有同时包含"宝马 多少 马力"的文档怎么做?就要使用 match_phrase 了

{
  "query": {
    "match_phrase": {
        "content" : {
            "query" : "我的宝马多少马力"
        }
    }
  }
}

完全匹配可能比较严,我们会希望有个可调节因子,少匹配一个也满足,那就需要使用到slop。

{
  "query": {
    "match_phrase": {
        "content" : {
            "query" : "我的宝马多少马力",
            "slop" : 1
        }
    }
  }
}

multi_match

如果我们希望两个字段进行匹配,其中一个字段有这个文档就满足的话,使用multi_match

{
  "query": {
    "multi_match": {
        "query" : "我的宝马多少马力",
        "fields" : ["title", "content"]
    }
  }
}

但是multi_match就涉及到匹配评分的问题了。

我们希望完全匹配的文档占的评分比较高,则需要使用best_fields

{
  "query": {
    "multi_match": {
      "query": "我的宝马发动机多少",
      "type": "best_fields",
      "fields": [
        "tag",
        "content"
      ],
      "tie_breaker": 0.3
    }
  }
}

意思就是完全匹配"宝马 发动机"的文档评分会比较靠前,如果只匹配宝马的文档评分乘以0.3的系数

我们希望越多字段匹配的文档评分越高,就要使用most_fields

{
  "query": {
    "multi_match": {
      "query": "我的宝马发动机多少",
      "type": "most_fields",
      "fields": [
        "tag",
        "content"
      ]
    }
  }
}

我们会希望这个词条的分词词汇是分配到不同字段中的,那么就使用cross_fields

{
  "query": {
    "multi_match": {
      "query": "我的宝马发动机多少",
      "type": "cross_fields",
      "fields": [
        "tag",
        "content"
      ]
    }
  }
}

term

term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇

{
  "query": {
    "term": {
      "content": "汽车保养"
    }
  }
}

查出的所有文档都包含"汽车保养"这个词组的词汇。

使用term要确定的是这个字段是否“被分析”(analyzed),默认的字符串是被分析的。

拿官网上的例子举例:

mapping是这样的:

PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "full_text": {
          "type":  "string"
        },
        "exact_value": {
          "type":  "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}

PUT my_index/my_type/1
{
  "full_text":   "Quick Foxes!",
  "exact_value": "Quick Foxes!"  
}

其中的full_text是被分析过的,所以full_text的索引中存的就是[quick, foxes],而extra_value中存的是[Quick Foxes!]。

那下面的几个请求:

GET my_index/my_type/_search
{
  "query": {
    "term": {
      "exact_value": "Quick Foxes!"
    }
  }
}

请求的出数据,因为完全匹配

GET my_index/my_type/_search
{
  "query": {
    "term": {
      "full_text": "Quick Foxes!"
    }
  }
}

请求不出数据的,因为full_text分词后的结果中没有[Quick Foxes!]这个分词。

bool联合查询: must,should,must_not

如果我们想要请求"content中带宝马,但是tag中不带宝马"这样类似的需求,就需要用到bool联合查询。
联合查询就会使用到must,should,must_not三种关键词。

这三个可以这么理解

  • must: 文档必须完全匹配条件
  • should: should下面会带一个以上的条件,至少满足一个条件,这个文档就符合should
  • must_not: 文档必须不匹配条件

比如上面那个需求:

{
  "query": {
    "bool": {
      "must": {
        "term": {
          "content": "宝马"
        }
      },
      "must_not": {
        "term": {
          "tags": "宝马"
        }
      }
    }
  }
}本文转载自:http://www.cnblogs.com/yjf512/p/4897294.html
### Elasticsearch 中 `match` `term` 查询的区别 #### 1. 数据处理方式的不同 `term` 查询用于查找确切的术语,它不会对输入数据进行分析。因此,在索引阶段存储的数据是什么样,查询时就需要完全匹配该形式才能找到结果[^1]。相比之下,`match` 查询会在执行前自动分析所提供的文本内容。这种特性使得它可以针对已经过分析并存储为多个标记(tokens)的字段进行有效搜索[^4]。 #### 2. 字段类型的适用性差异 对于像 keyword 这样的未被分词器处理过的精确值字段来说,通常推荐使用 `term` 查询来实现精准检索需求;而对于 text 类型这样的会被默认标准分词器或其他指定分词策略拆分成若干子项后再存入倒排索引中的情况,则更适合采用能够理解这些分割单元之间关系并通过相应逻辑组合起来形成最终表达式的 `match` 或其他高级查询方法[^5]。 #### 3. 实际应用案例对比 假设有一个包含产品名称及其描述信息的商品数据库,并且我们希望找出所有名字正好等于 “Apple Watch Series 8”的记录: 如果直接运用未经修改的标准配置下的 `term` 操作符去尝试完成上述任务的话可能会遇到困难——除非原始字符串已经被事先设置成了不可再进一步分解的形式(即定义为了keyword),否则由于自然语言处理过程中不可避免的存在诸如大小写转换、去除停用词等一系列预处理动作的影响,“apple watch series 8” 可能早已被打散成单独几个独立的部分分别对应不同的词条位置了,此时单纯依靠简单的字面意义比较显然无法达到预期效果[^3]。 然而当我们改用支持内置解析功能的 `match` 版本来重新构建相同的请求参数列表之后却可以轻松解决这个问题,因为它内部会先按照既定规则把目标串切分为合适的片段然后再逐一对照可能存在的候选项集合直至发现符合条件的对象为止。 ```json // Example of a term query (exact match on keywords) { "query": { "term": { "product_name.keyword": "Apple Watch Series 8" } } } // Example of a match query (analyzed search against texts) { "query": { "match": { "product_description": "smartwatch with health monitoring features" } } } ``` 以上两个例子展示了如何根据不同业务场景选择合适的方式来进行高效的信息定位操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值