ES快速入门
概念
-
为什么常用数据库不适合做搜索
数据量小,简单的搜索功能时可以用到常用的数据库,如:后台管理系统里的常见的查询存储问题:数据量大的时候,比如上亿条数据的查询,就得去考虑分库分表
性能问题:模糊查询(如:条件为 %包包%)时用不到索引导致全表查询,查询效率相当慢
分词问题:当你输入关键字“LV包包”,常用数据库一般只能返回完全匹配“LV包包”的结果,而不会匹配返回“LV”或“包包”关键字的结果 -
官方核心概念
-
近实时(NRT Near RealTime)
写数据时:过1秒才会被搜索到,因为内部在分词、录入索引。 -
es搜索时:搜索和分析数据需要秒级出结果。
-
集群(Cluster)
包含一个或多个启动着es实例的机器群。通常一台机器起一个es实例。
默认集群名是“elasticsearch”,同一网络,同一集群名下的es实例会自动组成集群。 -
节点(Node)
一个es实例即为一个节点。 -
索引(Index)
即拥有相似文档的集合 -
类型(Type)
每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field。7.x版本正式被去除。 -
文档(Document)
es中的最小数据单元。一个document就像数据库中的一条记录。通常以json格式显示。
多个document存储于一个索引(Index)中。 -
映射(Mapping)
定义索引中的字段的名称;
定义字段的数据类型,比如字符串、数字、布尔;
字段,倒排索引的相关配置,比如设置某个字段为不被索引、记录 position 等。
-
概念对比
Elasticsearch | 关系型数据库(如Mysql) |
---|---|
索引Index | 数据库Database |
类型Type | 表Table |
文档Document | 数据行Row |
字段Field | 数据列Column |
映射Mapping | 约束 Schema |
ES的CURD
-
ES的使用全部遵循RESTful api
-
RESTful 接口的格式:
-
http://localhost:9200///[]
-
使用
PUT
请求方法,id必填,使用POST请求方法id会自动生成
-
-
这里测试软件使用的是
APIFOX
-
添加 请求方法PUT、POST
-
PUT
方式请求id是必填项,POST
方式请求id非必填。 -
http://127.0.0.1:9200/city/shenzhen/1
-
{ "name": "包严联产素", "area": [ "ex sit ut magna", "Excepteur esse commodo", "elit", "enim anim occaecat", "amet officia consectetur et" ] }
-
返回结果
-
{ "_index": "city", "_type": "shenzhen", "_id": "1", "_version": 2, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 2, "_primary_term": 1 }
-
如果使用一个ID重复添加那么就会把上一次创建的值替换掉,并且
result
的值会变成update
-
-
DELETE删除 请求方法DELETE
-
http://127.0.0.1:9200/city/shenzhen/1
-
返回结果
-
{ "_index": "city", "_type": "shenzhen", "_id": "1", "_version": 3, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 }
-
-
-
修改 请求方法POST、PUT
-
修改和添加的使用方法相同
-
只要在RESTful 的id参数位置填上要修改的id,然后填上要修改的数据
-
http://127.0.0.1:9200/city/shenzhen/{id}
-
返回数据
-
{ "_index": "city", "_type": "shenzhen", "_id": "1", "_version": 3, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 18, "_primary_term": 1 }
-
-
查询
-
查询方法
-
match_all 查询简单的 匹配所有文档。在没有指定查询方式时,它是默认的查
-
match 用于全文搜索或者精确查询,如果在一个精确值的字段上使用它, 例如数字、日期、布尔或者一个 not_analyzed 字符串字段,那么它将会精确匹配给定的值
-
range 查询找出那些落在指定区间内的数字或者时间 gt 大于;gte 大于等于;lt 小于;lte 小于等于
-
term 被用于精确值 匹配
-
terms terms 查询和 term 查询一样,但它允许你指定多值进行匹配
-
exists 查找那些指定字段中有值的文档
-
missing 查找那些指定字段中无值的文档
-
must 多组合查询 必须匹配这些条件才能被包含进来
-
must_not 多组合查询 必须不匹配这些条件才能被包含进来
-
should 多组合查询 如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分
-
filter 多组合查询 这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档
-
-
使用match方式搜索
-
用于全文搜索或者精确查询,如果在一个精确值的字段上使用它, 例如数字、日期、布尔或者一个 not_analyzed 字符串字段,那么它将会精确匹配给定的值
-
URL:
http://127.0.0.1:9200/city/_search
请求方式GET -
搜索0-10条,name字段有
入
字的数据显示出来 -
请求数据 { "query": { "match": { "name": "入" } } }
-
{ "took": 16, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 2.1699305, "hits": [ { "_index": "city", "_type": "shenzhen", "_id": "1XN4oIIB-eB81hInavDb", "_score": 2.1699305, "_source": { "name": "思入效力强公东", "area": [ "et", "dolore veniam aliquip voluptate sed", "ex Excepteur", "ut" ] } } ] } }
-
可以看到
name
字段有个入
字,其他不相关的数据没有展示出来 -
返回的字段解释
-
字段 解释 took 查询花费了多长时间 timed_out 是否超时 __shards 数据拆成1个分片,对于搜索请求,会打到所有的primary shard(或者是它的某个replica shard也可以),所以total和successful会是1;如果有多个分片就会是其他值 hits 查询的所命中的结果 hits的total 查询出来的结果有多少条 max_score 查询出来的结果的匹配系数,匹配度越高,数值越大 _source 所存储的内容
-
-
Tips:
- 不需要索引的字段,一定要明确定义出来,因为默认是自动建索引的
- 对于String类型的字段,不需要analysis(分词)的也需要明确定义出来,因为默认
也是会analysis的- 选择有规律的ID很重要,随机性太大的ID(比如UUID)不利于查询