elasticsearch 查询match和term

本文详细介绍了Elasticsearch中的查询方式,包括match查询、match_phrase查询、multi_match查询及term查询等,通过具体实例展示了如何灵活运用这些查询方式来提高搜索效果。

elasticsearch 查询(match和term)

2015-10-21 11:25 by 轩脉刃, 59734 阅读, 2 评论, 收藏编辑

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": "宝马"
        }
      }
    }
  }
}
Creative Commons License

专注Web开发50年。请加群:Thinking in Web

轩脉刃的技术日记,请关注同名公众号:{轩脉刃的刀光剑影},记录日常技术讨论和思考

本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

<think> 首先,用户的问题是:“我想了解Elasticsearchmatchterm的区别 请问Elasticsearchmatchterm的区别”。这直接要求解释Elasticsearch中的matchterm查询的区别。 根据系统级指令,我需要使用中文回答,结构清晰,逐步解决问题,并保证回答真实可靠。指令还要求行内数学表达式用$...$,但这里不涉及数学,所以不需要。独立公式用$$...$$,但同样不适用。LaTeX语法正确,但查询不是数学公式。生成相关问题,并在回答末尾添加引用标识。 用户提供了几个引用源: - 引用[1]:解释了term是完全匹配、精确查询,而match是模糊匹配、分词查询。 - 引用[2]:term用于精确匹配,不分词;match会分词。给出了例子。 - 引用[3]:term精确查询match模糊查询,并强调分词处理。 - 引用[4]:match会分词,term不会;match可能匹配多个词,而term匹配整个词。 这些引用都一致地描述了区别:term是精确匹配(不分词),而match是模糊匹配(分词)。 我的回答应该基于这些引用,确保真实可靠。结构上,我需要清晰、逐步地解释区别。 大纲回答结构: 1. **引言**:简要介绍matchterm查询Elasticsearch中的作用。 2. **区别总结**: - **term查询**:精确匹配,不进行分词。适用于关键词、数值等。 - **match查询**:模糊匹配,先分词再匹配。适用于文本搜索。 3. **详细解释**: - 使用示例或场景来说明。 - 引用中的关键点:term不分词,直接匹配;match分词后匹配。 4. **例子**:提供简单的查询示例来演示区别。 5. **注意事项**:如match如何使用分词器,term在keyword字段上的使用等。 6. **相关问题**:根据指令,生成相关问题,放在最后。 引用标识:在回答末尾自然地添加引用标识,例如[^1],引用提供的来源。 生成相关问题: - 基于主题:如match_phrase的作用、如何选择查询类型、性能比较等。 具体相关问题: 1. 什么是match_phrase查询?它match查询有什么区别? 2. 在哪些场景下应该使用term查询而不是match查询? 3. Elasticsearch中分词器对match查询的影响是什么? 确保回答真实可靠:基于提供的引用,避免编造信息。 最终回答格式: - 用中文。 - 结构清晰:段落分明。 - 结尾添加引用标识,如[^1]。 - 最后列出相关问题。 </think>### Elasticsearchmatchterm查询的区别 在Elasticsearch中,`match``term`查询是两种常用的搜索方式,但它们在工作原理应用场景上有显著差异。下面我将逐步解释它们的区别,确保回答基于可靠参考源。 #### 1. **核心区别总结** - **`term`查询**: 这是一种**精确匹配**方式。查询时,Elasticsearch不会对搜索词进行分词处理,而是直接与文档中的字段值进行完全匹配。类似于在字典中查找一个完整单词。它适用于数值、日期、布尔值或不需要分词的字符串(如ID、邮政编码)。例如: ```json GET /index/_search { "query": { "term": { "title.keyword": "jstat命令查看jvm的GC信息1" // 精确匹配整个字符串 } } } ``` 如果文档的字段值不是完全相同的词,查询将不返回结果[^2][^3]。 - **`match`查询**: 这是一种**模糊匹配**方式。查询前,Elasticsearch会先对搜索词进行分词处理(例如拆分成单个单词),然后匹配文档中分词后的词条。类似于在文章中搜索关键词。它适用于文本内容搜索,能处理部分匹配情况。例如: ```json GET /index/_search { "query": { "match": { "title": "love China" // 分词为 "love" "China",匹配任意一个 } } } ``` 这会匹配包含"love"或"China"的文档,因为分词后是"或"关系[^1][^4]。 #### 2. **详细工作机制对比** - **分词处理**: - `term`查询:**不分词**。搜索词被视为一个整体,直接与字段值比较。如果字段是文本类型(text),通常需要指定`.keyword`子字段来避免分词影响。 - `match`查询:**先分词**。搜索词通过分词器(如standard analyzer)拆分成词条(tokens),然后与文档中的分词匹配。匹配基于词条的出现频率位置计算相关性得分。 - **匹配逻辑**: - `term`查询:要求**完全一致**。例如搜索`"John Doe"`时,只匹配字段值完全为"John Doe"的文档,不会匹配包含"John"或"Doe"的文档[^2]。 - `match`查询:允许**部分匹配**。分词后,默认使用"或"逻辑(OR),匹配任意词条即可。可以通过参数调整为"与"逻辑(AND),要求所有词条都出现。例如搜索`"love China"`,如果文档包含"love""China"两个词,则匹配;但如果文档只有"love"或只有"China",也可能匹配[^4]。 - **适用场景**: - **使用`term`的场景**:精确值搜索,如用户ID、状态码、枚举类型。例如过滤订单状态为"paid"的文档。 - **使用`match`的场景**:全文搜索,如文章内容、产品描述。例如在日志中搜索"error message"关键词。 - **性能考虑**: - `term`查询通常更快,因为它无需分词,直接利用倒排索引的精确查找。 - `match`查询涉及分词相关性计算,开销较大,但更灵活,适合模糊搜索[^1][^3]。 #### 3. **实际例子说明** 假设索引中有文档: ```json { "title": "I love China" }, { "title": "Hubei province" }, { "title": "China news" } ``` - `term`查询`"China"`:无结果,因为字段值不是完全匹配"China"(如"China news"包含额外词)。 - `match`查询`"China"`:匹配所有包含"China"的文档(如"China news""I love China"),因为分词后"China"单独匹配[^3][^4]。 若需同时匹配多个词(如"love""China"),可用`match_phrase`查询代替`match`,它要求词条按顺序出现[^4]。 #### 注意事项 - **字段类型影响**:`term`查询在keyword字段上效果最佳;`match`查询适用于text字段。确保映射(mapping)正确设置。 - **相关性排序**:`match`查询默认按相关性得分排序(得分高者优先),而`term`查询无此机制。 - **组合使用**:实践中,常将`term`用于过滤,`match`用于搜索,通过`bool`查询结合两者[^1][^2]。 总之,`term`强调精确性,`match`强调灵活性。选择哪种取决于搜索需求:精确匹配用`term`,模糊搜索用`match`[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值