Elasticsearch搜索引擎学习笔记(五)
搜索功能
数据准备
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搜索引擎学习笔记(五)的更多相关文章
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
		好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ... 
- (转)Qt Model/View 学习笔记 (五)——View 类
		Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ... 
- java之jvm学习笔记五(实践写自己的类装载器)
		java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ... 
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
		中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ... 
- Typescript 学习笔记五:类
		中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ... 
- ES6学习笔记<五> Module的操作——import、export、as
		import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ... 
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
		目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ... 
- python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍
		python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ... 
- Go语言学习笔记五: 条件语句
		Go语言学习笔记五: 条件语句 if语句 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } 竟然没有括号,和python很像.但是有大括号,与python又不一样. 例子: pa ... 
- 【opencv学习笔记五】一个简单程序:图像读取与显示
		今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ... 
随机推荐
- 关于 Span 的一切:探索新的 .NET 明星: 4. Span<T> 和 Memory<T> 是如何与 .NET 库集成的?
			4. Span<T> 和 Memory<T> 是如何与 .NET 库集成的? 1. Span<T> 是什么? 2. Span<T> 是如何实现的? 3. ... 
- kubeadm安装  k8s集群证书过期更新
			kubeadm安装 k8s集群证书过期更新 kubeadm版本 v1.18.8 #查看证书 #mast节点,查看所有证书 kubeadm alpha certs check-expiration #若 ... 
- 【Linux】【UOS】为挂载的磁盘创建快捷方式(软链接)
			打开项目或者保存文件的时候,如果需求路径不是系统盘路径,那么找起来还真是麻烦.以下时候通过创建快捷方式(软链接)的方式,将打开磁盘的快捷方式放在用户目录下,就方便寻找打开了. 1.查询挂载点 sudo ... 
- [转]ubuntu20.04使用dev-sidecar找不到安装证书
			火狐.chrome等浏览器不走系统证书,火狐.谷歌浏览器必须在浏览器上安装证书 然后死活找不到证书,搜索了整个目录也没有. 原来是我的显示隐藏文件没打开.打开目录的"显示隐藏文件" ... 
- 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 ... 
- Intellij IDEA如何导入 Maven 项目
			Intellij IDEA如何导入 Maven 项目 选择 File->Import Module,选择 Maven 模块路径,如下图所示: 选择"Import module from ... 
- 昔日移动端IM明星 “米聊” 即将停止服务
			2021年1月19日,小米旗下米聊宣布,将于2021年2月19日12点停止米聊的服务. 1.以下消息来自米聊官网 2.关于米聊 米聊是小米科技出品的一款免费即时通讯工具,推出时间为:2010年12 ... 
- gRPC编译与字段编号的细节探讨
			上次我们专门通过一个简单的HelloWorld示例来了解了gRPC的基本概念和使用方法.今天,我们将继续深入探讨gRPC,重点讨论一些在实际应用中需要特别注意的要点.实际上,gRPC的核心目标是简化远 ... 
- WPF页面中将一个控件的宽度绑定到其父级用户控件的实际宽度
			该实际场景比较常见于,当存在多个用户控件页面拼成一个窗体,因为实际控件对应窗体的宽度并不能确定,也不是那种能指定的宽度或者高度,比如窗体分导航区域和内容区域,左侧导航区域可以直接指定宽度,而右侧内容区 ... 
- elsa工作流-调度(安排后台作业)
			前言 elsa内部很多地方都会用到后台作业,也就是在后台线程中执行一堆任务,这与我们通常理解的后台作业没有区别. elsa将后台作业也称为调度Schedul,相关功能由Elsa.Scheduling模 ... 
