草庐IT

Elasticsearch专栏-5.es基本用法-分词查询

zjun1001 2023-04-11 原文

es基本用法-分词查询

什么是分词

所谓分词,就是把一段语句,分割成一个个单词的过程。比如"717 Hendrickson Place"短语,分词后就是三个单词,即717、hendrickson、place。注意,分词后的单词默认都是小写。
分词查询,指的就是查询时,把要查询的语句(字符串)先进行分词,然后拿分词后的单词去文档集合中比对。只要包含分词后的任意一个单词,就算命中结果。

如何查看分词结果

1.查看指定短语分词结果

GET _analyze
{
  "analyzer":"standard",
  "text":"717 Hendrickson Place"
}


分词结果中,有几个关键字:token、start_offset、end_offset、position。它们的含义说明如下:

关键字含义
token分词后的单词,小写
start_offset在整个短语字符串中的开始位置,相当于数组下标
end_offset在整个短语字符串中的结束位置,相当于数组下标
position单词在整个短语的位置,即第几个单词

2.查看索引下某个字段分词结果

GET /bank/_analyze
{
  "field":"address",
  "text":"717 Hendrickson Place" 
}

3.查看单个文档某个字段分词结果
原始文档数据

GET /bank/_doc/1

分词后数据

GET /bank/_doc/1/_termvectors?fields=address

分词涉及关键字说明

分词查询中,经常涉及几个关键字,如text、keyword、match、term。很多人都会混淆,不明白彼此间有何区别。下面就重点解释下。

text和keyword

  1. text和keyword是数据类型,针对的是数据写入,写入到磁盘上是否进行分词。
  2. text会分词,也就是说,在数据落盘时,会被分割成多个独立的单词,然后存入倒排索引中。分词查询时候,也是以单词维度进行匹配。
  3. keyword不会分词,存的的是整个短语。

match和term

  1. match和term,是两种搜索方式,针对的是数据查询,要查询的短语是否进行分词。
  2. match搜索时候,会对被搜索的内容进行分词,然后拿分词后的内容,去倒排索引中查询。
  3. term是不对被搜索内容进行分词,就是完全匹配。

举例说明

term+keyword:有结果

POST /bank/_search
{
	"query": {
		"term": {
			"address.keyword": "717 Hendrickson Place"
		}
	}
}


term+keyword:没有结果(这里改动了place)

POST /bank/_search
{
	"query": {
		"term": {
			"address.keyword": "717 Hendrickson Place01"
		}
	}
}


match+keyword:有结果

POST /bank/_search
{
	"query": {
		"match": {
			"address.keyword": "717 Hendrickson Place"
		}
	}
}


match+keyword:没有结果(这里改动了place)

POST /bank/_search
{
	"query": {
		"match": {
			"address.keyword": "717 Hendrickson Place01"
		}
	}
}


term+text:没有结果

POST /bank/_search
{
	"query": {
		"term": {
			"address": "717 Hendrickson Place"
		}
	}
}


match+text:有结果

POST /bank/_search
{
	"query": {
		"match": {
			"address": "717 Hendrickson Place"
		}
	}
}


match+text:有结果(这里改动了place)

POST /bank/_search
{
	"query": {
		"match": {
			"address": "717 Hendrickson Place01"
		}
	}
}


term+text:没有结果

POST /bank/_search
{
	"query": {
		"term": {
			"address": "Hendrickson"
		}
	}
}


term+text:有结果(Hendrickson改成小写hendrickson)

POST /bank/_search
{
	"query": {
		"term": {
			"address": "hendrickson"
		}
	}
}

分词查询:match_phrase

先看下例子,此时能查到结果

POST /bank/_search
{
  "query":{
    "match_phrase":{
      "address": "467 Hutchinson"
    }
  }
}


下面这种查不到结果(Hutchinson改为了Hutchinson01)

POST /bank/_search
{
  "query":{
    "match_phrase":{
      "address": "467 Hutchinson01"
    }
  }
}


同样的查询语句,此时改为match,能查到结果

POST /bank/_search
{
  "query":{
    "match":{
      "address": "467 Hutchinson01"
    }
  }
}

很多文章把match_phrase查询称为短语查询,只要结果中全部包含待查询语句即可。从现象来看,这种解释也没错,但很容易让人误以为match_phrase查询时,不对待查询语句进行分词,就是SQL中like的功能。这种是不对的。
从上面对比中可以看出来,match_phrase和match是不一样的。match是对待查询语句先分词,然后再去文档集合中查询。只要包含分词后的任意一个单词,就算是命中。但match_phrase不是这样,它也会先分词,不过查询时候必须全部包含分词后的所有单词,其单词前后顺序也要一样。
下面把上述短语中单词顺序调换下,在测试看

POST /bank/_search
{
  "query":{
    "match_phrase":{
      "address": "Hutchinson 467"
    }
  }
}


此时可以看到,单词顺序颠倒后,match_phrase是查不到结果的。match仍然可以。
总结:match_phrase和match查询时候,都会先分词再查询。match要求不高,只要匹配到分词后的任意一个单词,就算查到结果。而match_phrase要求严格,不仅要求,要能够匹配到分词后的所有单词,且分词后的单词顺序也要和命中结果中的顺序保持一致。这样才算查到结果

有关Elasticsearch专栏-5.es基本用法-分词查询的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  3. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  4. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  5. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  6. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  7. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  8. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

  9. ruby-on-rails - solr 清理查询 - 2

    我在Rails上使用带有ruby​​的solr。一切正常,我只需要知道是否有任何现有代码来清理用户输入,比如以?开头的查询。或* 最佳答案 我不知道执行此操作的任何代码,但理论上可以通过查看parsingcodeinLucene来完成并搜索thrownewParseException(只有16个匹配!)。在实践中,我认为您最好只捕获代码中的任何solr异常并显示“无效查询”消息或类似信息。编辑:这里有几个“sanitizer”:http://pivotallabs.com/users/zach/blog/articles/937-s

  10. ruby-on-rails - Rails 3 在一个查询中包含多个表 - 2

    我正在为锦标赛开发一个Rails应用程序。我在这个查询中使用了三个模型:classPlayertruehas_and_belongs_to_many:tournamentsclassTournament:destroyclassPlayerMatch"Player",:foreign_key=>"player_one"belongs_to:player_two,:class_name=>"Player",:foreign_key=>"player_two"在tournaments_controller的显示操作中,我调用以下查询:Tournament.where(:id=>params

随机推荐