搜索功能

数据准备

  1、自定义词库

    慕课网

    慕课

    课网

    慕

    课

    网

  2、新建立索引shop

  3、建立mappings

POST        /shop/_mapping        (7.x之前的版本:/shop/_mapping/_doc)
{
"properties": {
"id": {
"type": "long"
},
"age": {
"type": "integer"
},
"username": {
"type": "keyword"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word"
},
"money": {
"type": "float"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word"
},
"sex": {
"type": "byte"
},
"birthday": {
"type": "date"
},
"face": {
"type": "text",
"index": false
}
}
}

  4、录入数据

POST         /shop/_doc/1001

{
"id": 1001,
"age": 18,
"username": "imoocAmazing",
"nickname": "慕课网",
"money": 88.8,
"desc": "我在慕课网学习java和前端,学习到了很多知识",
"sex": 0,
"birthday": "1992-12-24",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1002,
"age": 19,
"username": "justbuy",
"nickname": "周杰棍",
"money": 77.8,
"desc": "今天上下班都很堵,车流量很大",
"sex": 1,
"birthday": "1993-01-24",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1003,
"age": 20,
"username": "bigFace",
"nickname": "飞翔的巨鹰",
"money": 66.8,
"desc": "慕课网团队和导游坐飞机去海外旅游,去了新马泰和欧洲",
"sex": 1,
"birthday": "1996-01-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1004,
"age": 22,
"username": "flyfish",
"nickname": "水中鱼",
"money": 55.8,
"desc": "昨天在学校的池塘里,看到有很多鱼在游泳,然后就去慕课网上课了",
"sex": 0,
"birthday": "1988-02-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1005,
"age": 25,
"username": "gotoplay",
"nickname": "ps游戏机",
"money": 155.8,
"desc": "今年生日,女友送了我一台play station游戏机,非常好玩,非常不错",
"sex": 1,
"birthday": "1989-03-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1006,
"age": 19,
"username": "missimooc",
"nickname": "我叫小慕",
"money": 156.8,
"desc": "我叫凌云慕,今年20岁,是一名律师,我在琦䯲星球做演讲",
"sex": 1,
"birthday": "1993-04-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1007,
"age": 19,
"username": "msgame",
"nickname": "gamexbox",
"money": 1056.8,
"desc": "明天去进货,最近微软处理很多游戏机,还要买xbox游戏卡带",
"sex": 1,
"birthday": "1985-05-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1008,
"age": 19,
"username": "muke",
"nickname": "慕学习",
"money": 1056.8,
"desc": "大学毕业后,可以到imooc.com进修",
"sex": 1,
"birthday": "1995-06-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1009,
"age": 22,
"username": "shaonian",
"nickname": "骚年轮",
"money": 96.8,
"desc": "骚年在大学毕业后,考研究生去了",
"sex": 1,
"birthday": "1998-07-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1010,
"age": 30,
"username": "tata",
"nickname": "隔壁老王",
"money": 100.8,
"desc": "隔壁老外去国外出差,带给我很多好吃的",
"sex": 1,
"birthday": "1988-07-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1011,
"age": 31,
"username": "sprder",
"nickname": "皮特帕克",
"money": 180.8,
"desc": "它是一个超级英雄",
"sex": 1,
"birthday": "1989-08-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
} {
"id": 1012,
"age": 31,
"username": "super hero",
"nickname": "super hero",
"money": 188.8,
"desc": "BatMan, GreenArrow, SpiderMan, IronMan... are all Super Hero",
"sex": 1,
"birthday": "1980-08-14",
"face": "https://www.imooc.com/static/img/index/logo.png"
}

请求参数的查询(QueryString)

GET     /shop/_doc/_search?q=desc:慕课网
GET /shop/_doc/_search?q=nickname:慕&q=age:25

DSL查询

QueryString用的很少,一旦参数复杂就难以构建,所以大多查询都会使用dsl来进行查询更好。

# 查询
POST /shop/_doc/_search
{
"query": {
"match": {
"desc": "慕课网"
}
}
}
# 判断某个字段是否存在
{
"query": {
"exists": {
"field": "desc"
}
}
}

查询所有

GET     /shop/_doc/_search

或

POST     /shop/_doc/_search
{
"query": {
"match_all": {}
},
"_source": ["id", "nickname", "age"]
}  

分页

POST     /shop/_doc/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 10
} {
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
],
"from": 0,
"size": 10
}

  

term精确搜索与match分词搜索

term搜索的时候会把用户搜索内容,比如“慕课网强大”作为一整个关键词去搜索,而不会对其进行分词后再搜索;

match会把用户搜索内容分词,然后再搜索

POST     /shop/_doc/_search
{
"query": {
"term": {
"desc": "慕课网"
}
}
}
对比
{
"query": {
"match": {
"desc": "慕课网"
}
}
}

  

terms 多个词语匹配检索

POST     /shop/_doc/_search
{
"query": {
"terms": {
"desc": ["慕课网", "学习", "骚年"]
}
}
}

  

match_phrase 短语匹配

match:分词后只要有匹配就返回,match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。(搜索比较严格)

slop:允许词语间跳过的数量,是“词”的数量,不是“字”的数量

POST     /shop/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业 研究生",
"slop": 2
}
}
}
}

  

match(operator)

operator

  or:搜索内容分词后,只要存在一个词语匹配就展示结果

  and:搜索内容分词后,都要满足词语匹配。

POST     /shop/_doc/_search
{
"query": {
"match": {
"desc": "慕课网"
}
}
}
# 等同于
{
"query": {
"match": {
"desc": {
"query": "xbox游戏机",
"operator": "or"
}
}
}
}
# 相当于 select * from shop where desc='xbox' or|and desc='游戏机'

  

match(minimum_should_match)

minimum_should_match

  minimum_should_match: 最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整。举个例子:当前属性设置为<code>70</code>,若一个用户查询检索内容分词后有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则 8x70%=5.6,则desc中至少需要有5个词语匹配,就展示。

  minimum_should_match 也能设置具体的数字,表示个数

POST     /shop/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "女友生日送我好玩的xbox游戏机",
"minimum_should_match": "60%"
}
}
}
}

  

根据文档主键ids搜索

GET /shop/_doc/1001

或

POST     /shop/_doc/_search

{
"query": {
"ids": {
"type": "_doc",
"values": ["1001", "1010", "1008"]
}
}
}

  

multi_match/boost

multi_match

  满足使用match在多个字段中进行查询的需求

POST     /shop/_doc/_search
{
"query": {
"multi_match": {
"query": "皮特帕克慕课网",
"fields": ["desc", "nickname"] }
}
}

  

boost

  权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。

  nickname^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个nickname为主,desc为辅,nickname的匹配相关度当然要提高权重比例了。

POST     /shop/_doc/_search
{
"query": {
"multi_match": {
"query": "皮特帕克慕课网",
"fields": ["desc", "nickname^10"] }
}
}

  

布尔查询

可以组合多重查询

  must:查询必须匹配搜索条件,譬如 and
  should:查询匹配满足1个以上条件,譬如 or
  must_not:不匹配搜索条件,一个都不要满足

POST     /shop/_doc/_search

{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "慕课网",
"fields": ["desc", "nickname"]
}
},
{
"term": {
"sex": 1
}
},
{
"term": {
"birthday": "1996-01-14"
}
}
]
}
}
} {
"query": {
"bool": {
"should(must_not)": [
{
"multi_match": {
"query": "学习",
"fields": ["desc", "nickname"]
}
},
{
"match": {
"desc": "游戏"
}
},
{
"term": {
"sex": 0
}
}
]
}
}
}
{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "慕"
}
},
{
"match": {
"nickname": "慕"
}
}
],
"should": [
{
"match": {
"sex": "0"
}
}
],
"must_not": [
{
"term": {
"birthday": "1992-12-24"
}
}
]
}
}
}

  

为指定词语加权

特殊场景下,某些词语可以单独加权,这样可以排得更加靠前。

POST     /shop/_doc/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"desc": {
"query": "律师",
"boost": 18
}
}
},
{
"match": {
"desc": {
"query": "进修",
"boost": 2
}
}
}
]
}
}
}

  

过滤器

对搜索出来的结果进行数据过滤。不会到es库里去搜,不会去计算文档的相关度分数,所以过滤的性能会比较高,过滤器可以和全文搜索结合在一起使用。

post_filter元素是一个顶层元素,只会对搜索结果进行过滤。不会计算数据的匹配度相关性分数,不会根据分数去排序,query则相反,会计算分数,也会按照分数去排序。

  query:根据用户搜索条件检索匹配记录

  post_filter:用于查询后,对结果数据的筛选

POST     /shop/_doc/_search

{
"query": {
"match": {
"desc": "慕课网游戏"
}
},
"post_filter": {
"range": {
"money": {
"gt": 60,
"lt": 1000
}
}
}
}

  上边是关键词是“慕课网游戏”,并且过滤条件是“money”大于60且小于1000的。

  现在改一下,关键词是“慕课网游戏”,并且过滤条件是“money”小于60或大于1000的,这个该怎么写呢?答案如下:

{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "慕课网"
}
}
],
"should": [
{
"range": {
"money": {
"lt": 60
}
}
},
{
"range": {
"money": {
"gt": 1000
}
}
}
],
"minimum_should_match":1
}
}
}

  

排序

POST     /shop/_doc/_search
{
"query": {
"match": {
"desc": "慕课网游戏"
}
},
"post_filter": {
"range": {
"money": {
"gt": 55.8,
"lte": 155.8
}
}
},
"sort": [
{
"age": "desc"
},
{
"money": "desc"
}
]
}

  由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。

  创建新的索引

POST        /shop2/_mapping
{
"properties": {
"id": {
"type": "long"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}

  

  插入数据

POST         /shop2/_doc
{
"id": 1001,
"nickname": "美丽的风景"
}
{
"id": 1002,
"nickname": "漂亮的小哥哥"
}
{
"id": 1003,
"nickname": "飞翔的巨鹰"
}
{
"id": 1004,
"nickname": "完美的天空"
}
{
"id": 1005,
"nickname": "广阔的海域"
}

  

  排序

{
"sort": [
{
"nickname.keyword": "desc"
}
]
}

  

                              整理自慕课网《java架构师体系课》

Elasticsearch搜索引擎学习笔记(五)的更多相关文章

  1. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  2. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  3. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  5. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  7. muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor

    目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...

  8. python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍

    python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...

  9. Go语言学习笔记五: 条件语句

    Go语言学习笔记五: 条件语句 if语句 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } 竟然没有括号,和python很像.但是有大括号,与python又不一样. 例子: pa ...

  10. 【opencv学习笔记五】一个简单程序:图像读取与显示

    今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ...

随机推荐

  1. 关于 Span 的一切:探索新的 .NET 明星: 4. Span<T> 和 Memory<T> 是如何与 .NET 库集成的?

    4. Span<T> 和 Memory<T> 是如何与 .NET 库集成的? 1. Span<T> 是什么? 2. Span<T> 是如何实现的? 3. ...

  2. kubeadm安装 k8s集群证书过期更新

    kubeadm安装 k8s集群证书过期更新 kubeadm版本 v1.18.8 #查看证书 #mast节点,查看所有证书 kubeadm alpha certs check-expiration #若 ...

  3. 【Linux】【UOS】为挂载的磁盘创建快捷方式(软链接)

    打开项目或者保存文件的时候,如果需求路径不是系统盘路径,那么找起来还真是麻烦.以下时候通过创建快捷方式(软链接)的方式,将打开磁盘的快捷方式放在用户目录下,就方便寻找打开了. 1.查询挂载点 sudo ...

  4. [转]ubuntu20.04使用dev-sidecar找不到安装证书

    火狐.chrome等浏览器不走系统证书,火狐.谷歌浏览器必须在浏览器上安装证书 然后死活找不到证书,搜索了整个目录也没有. 原来是我的显示隐藏文件没打开.打开目录的"显示隐藏文件" ...

  5. Type of the default value for 'data' prop must be a function的解决方法

    Type of the default value for 'data' prop must be a function的解决方法 问题现象 在写形如prop: {type: Array; defau ...

  6. Intellij IDEA如何导入 Maven 项目

    Intellij IDEA如何导入 Maven 项目 选择 File->Import Module,选择 Maven 模块路径,如下图所示: 选择"Import module from ...

  7. 昔日移动端IM明星 “米聊” 即将停止服务

    2021年1月19日,小米旗下米聊宣布,将于2021年2月19日12点停止米聊的服务. 1.以下消息来自米聊官网   2.关于米聊 米聊是小米科技出品的一款免费即时通讯工具,推出时间为:2010年12 ...

  8. gRPC编译与字段编号的细节探讨

    上次我们专门通过一个简单的HelloWorld示例来了解了gRPC的基本概念和使用方法.今天,我们将继续深入探讨gRPC,重点讨论一些在实际应用中需要特别注意的要点.实际上,gRPC的核心目标是简化远 ...

  9. WPF页面中将一个控件的宽度绑定到其父级用户控件的实际宽度

    该实际场景比较常见于,当存在多个用户控件页面拼成一个窗体,因为实际控件对应窗体的宽度并不能确定,也不是那种能指定的宽度或者高度,比如窗体分导航区域和内容区域,左侧导航区域可以直接指定宽度,而右侧内容区 ...

  10. elsa工作流-调度(安排后台作业)

    前言 elsa内部很多地方都会用到后台作业,也就是在后台线程中执行一堆任务,这与我们通常理解的后台作业没有区别. elsa将后台作业也称为调度Schedul,相关功能由Elsa.Scheduling模 ...