当前位置:   article > 正文

ElasticSearch入门及进阶实战(1) 基础入门_elasticsearch搜索引擎构建入门与实战

elasticsearch搜索引擎构建入门与实战

 

简介

什么是elasticsearch

    elasticsearch是开源的分布式、Restfull  风格的数据搜索与分析引擎,是时下最流行的全文搜索引擎。

elasticsearch和Apache Lucene

    Apache Lucene是时下最先进、高性能、全功能的搜索引擎库,Apache Lucene原理和实现复杂。elasticsearch就是为了解决Lucene复杂性的,elasticsearch基于Lucene,使用java语言开发,对Lucene做了一层封装,提供一套简单一致的Restfull 风格API,是的全文检索更简单。

elasticsearch不仅仅是全文搜索引擎:

  • 一个分布式实时文档存储,每个字段都可以被索引和搜索。
  • 一个分布式实时分析搜索引擎。
  • 支持上百个服务节点扩展,支持PB级的结构化数据和非结构化数据。

安装运行

Windows下安装

  1. step1 安装Kibana 下载Elasticsearch 6.2.2的zip包,并解压到指定目录,下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2
  2. step2 安装中文分词插件,在elasticsearch-6.2.2\bin目录下执行以下命令
  3. elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-analysis-ik-6.2.2.zip
  4. step3 启动es 运行es安装目录/bin/elasticsearch.bat
  5. step4 安装Kibana 下载Kibana,作为访问Elasticsearch的客户端,请下载6.2.2版本的zip包,并解压到指定目录,下载地址:https://artifacts.elastic.co/downloads/kibana/kibana-6.2.2-windows-x86_64.zip
  6. step5 启动Kibana 运行Kibana/bin/kibana.bat

linux下安装

  1. step1 下载elasticsearch 6.4.0的docker镜像;
  2. docker pull elasticsearch:6.4.0
  3. step2 修改虚拟内存区域大小,否则会因为过小而无法启动;
  4. sysctl -w vm.max_map_count=262144
  5. step3 修改该目录的权限,使es有权访问目录
  6. chmod 777 /mydata/elasticsearch/data/
  7. step4 使用docker命令启动;
  8. docker run -p 9200:9200 -p 9300:9300 --name elasticsearch \
  9. -e "discovery.type=single-node" \
  10. -e "cluster.name=elasticsearch" \
  11. -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
  12. -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
  13. -d elasticsearch:6.4.0
  14. step5 安装中文分词器IKAnalyzer,并重新启动;
  15. docker exec -it elasticsearch /bin/bash
  16. #此命令需要在容器中运行
  17. #进入ES目录
  18. docker exec -it elasticsearch /bin/bash
  19. elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.0/elasticsearch-analysis-ik-6.4.0.zip
  20. docker restart elasticsearch
  21. step6 访问es测试安装是否成功
  22. http://linux服务器:9200/
  23. step7 下载kibana 6.4.0的docker镜像
  24. step8 docker命令启动
  25. docker run --name kibana -p 5601:5601 \
  26. --link elasticsearch:es \
  27. -e "elasticsearch.hosts=http://es:9200" \
  28. -d kibana:6.4.0
  29. step8 访问测试安装是否成功
  30. http://linux服务器地址:5601

Kibana是es可视化用户界面,在DevTol下可以使用es DSL语言操纵ES。

elasticsearch基本概念

全文搜索(Full-Text Search):计算机检索程序通过扫描文章每一个词,对每一个词建立索引,指明该词在文章中出现次数和位置。当用户查询时,检索程序根据事先建立的索引进行查询并返回查询结果给用户的查询方式。

倒排索引(Inverted Index):

  • 该索引表中每一项都包括一个属性值和具有该属性值的各记录的地址;
  • 该索引表不是由记录确认属性值,而是由属性值来确定记录的位置,因此成为倒排索引;
  • elasticsearch能够实现高效、快速搜索功能,正是基于倒排索引。

节点 &集群(Node & Cluster):elasticsearch本质是分布式数据库,允许多台服务器共同工作。每台服务器可以运行多个es实例,单个实例就是节点(Node),一组节点构成集群(Cluster)。

索引(Index):elasticsearch管理数据的顶层单位,Index必须小写英文命名。Index相当于关系数据库中的数据库。

文档(Document):Index中的单条记录称为Document,Document使用JSON格式表示。同一个Index下Document不要求具有相同数据结构(Scheme),但是最好保持一致,这样可以提供搜索效率。

类型(Type):

  • Document可以分组,比如Order这个Index,可以按订单状态分组,可以按订单类型分组,这个分组称为Type。
  • elasticsearch Tyoe是虚拟逻辑分组,用来过滤Document,Type相当于关系数据库中的数据表;
  • 一个Index下不同Type应该有相似结构,完全不同数据结构的数据应该建立不同Index。

文档元数据:文档元数据可以分为三部分

  • _index: 文档存放位置
  • -Type: 文档类型
  • _id: 文档唯一标识

三者可以唯一表示一个文档。

字段:Document是一个JSON数据结构,包含许多字段,每个字段都有对应值。字段相当于关系数据库中的字段。

                                                                      es和关系数据库类比图

elasticsearch入门

elasticsearch交互方式

elasticsearch提供Java API 和 Restfull API。基于Restfull API 其他语言程序可以通过9200端口和es进行通讯。

elasticsearch 请求分析

部件说明
VERB适当的HTTP方法或谓词:GET\PUT\DELETE\POST\HEAD。
PROTOCOLhttp或https(如果elasticsearch前面启用了代理)
HOSTelasticsearch集群中任一节点主机名或者用localhost代表本地节点
PORTelasticsearch端口号,默认9200
PATHAPI终端路径(如_count将返回集群中文档数量)。PATH可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm
QUERY_STRING任意可选的查询字符串参数,例如:?pretty 将格式化地输出 JSON 返回值,使其更容易阅读
BODY一个JSON格式请求体

 

 

 

 

 

 

 

HTTP方法说明

HTTP方法说明
GET获取请求对象当前状态
PUT创建一个对象
POST改变当前对象状态
DELETE删除一个对象
HEAD获取对象的基础信息

 

 

 

 

 

基础命令详解

查看集群健康状态:

GET /_cat/health?v

查看节点状态:

GET /_cat/nodes?v

查看所有索引信息:

GET /_cat/indices?v

创建索引并查看;

  1. PUT /customer
  2. GET /_cat/indices?v

删除索引并查看:

  1. DELETE /customer
  2. GET /_cat/indices?v

查看文档的类型:

GET /pms/_mapping

在索引中添加文档

  1. PUT /customer/doc/1
  2. {
  3. "name": "John Doe"
  4. }

查看索引中的文档

  1. GET /customer/doc/1
  2. {
  3. "_index": "customer",
  4. "_type": "doc",
  5. "_id": "1",
  6. "_version": 1,
  7. "found": true,
  8. "_source": {
  9. "name": "John Doe"
  10. }
  11. }

修改索引中的文档:

  1. POST /customer/doc/1/_update
  2. {
  3. "doc": { "name": "Jane Doe" }
  4. }
  5. {
  6. "_index": "customer",
  7. "_type": "doc",
  8. "_id": "1",
  9. "_version": 2,
  10. "result": "updated",
  11. "_shards": {
  12. "total": 2,
  13. "successful": 1,
  14. "failed": 0
  15. },
  16. "_seq_no": 1,
  17. "_primary_term": 1
  18. }
  19. GET /customer/doc/1
  20. {
  21. "_index": "customer",
  22. "_type": "doc",
  23. "_id": "1",
  24. "_version": 2,
  25. "found": true,
  26. "_source": {
  27. "name": "Jane Doe"
  28. }
  29. }

删除索引中文档:

DELETE /customer/doc/1

对索引文档进行批量操作

  1. POST /customer/doc/_bulk
  2. {"index":{"_id":"1"}}
  3. {"name": "John Doe" }
  4. {"index":{"_id":"2"}}
  5. {"name": "Jane Doe" }

数据搜索

elasticsearch提供了丰富灵活的查询语言-查询表达式(Query DSL),支持构建更加复杂和健壮的查询。

最简单的搜索,使用match_all来表示,例如搜索全部:

  1. GET /pms/_search
  2. {
  3. "query": { "match_all": {} }
  4. }

分页搜索,from表示偏移量,从0开始,size表示每页显示的数量;

  1. GET /pms/_search
  2. {
  3. "query": { "match_all": {} },
  4. "from": 0,
  5. "size": 3
  6. }

搜索排序,使用sort表示,例如按price字段降序排列;

  1. GET /pms/_search
  2. {
  3. "query": { "match_all": {} },
  4. "sort": { "price": { "order": "desc" } }
  5. }

搜索并返回指定字段内容,使用_source表示,例如只返回nameprice两个字段内容:

  1. GET /pms/_search
  2. {
  3. "query": { "match_all": {} },
  4. "_source": ["name", "price"]
  5. }

条件搜索,使用match表示匹配条件,例如搜索出price98的文档:

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "match": {
  5. "price": 98
  6. }
  7. }
  8. }

文本类型字段的条件搜索,例如搜索address字段中包含mill的文档,对比上一条搜索可以发现,对于数值类型match操作使用的是精确匹配,对于文本类型使用的是模糊匹配:

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "match": {
  5. "name": "海澜之家"
  6. }
  7. },
  8. "_source": [
  9. "name",
  10. "subTitle"
  11. ]
  12. }
  1. {
  2. "took": 7,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": 3,
  12. "max_score": 4.2882357,
  13. "hits": [
  14. {
  15. "_index": "pms",
  16. "_type": "product",
  17. "_id": "30",
  18. "_score": 4.2882357,
  19. "_source": {
  20. "subTitle": "2018夏季新品微弹舒适新款短T男生 6月6日-6月20日,满300减30,参与互动赢百元礼券,立即分享赢大奖",
  21. "name": "HLA海澜之家简约动物印花短袖T恤"
  22. }
  23. },
  24. {
  25. "_index": "pms",
  26. "_type": "product",
  27. "_id": "32",
  28. "_score": 4.2882357,
  29. "_source": {
  30. "subTitle": "HLA海澜之家短袖T恤男基础款简约圆领HNTBJ2E153A藏青(F3)175/92A(50)",
  31. "name": "HLA海澜之家短袖T恤男基础款"
  32. }
  33. },
  34. {
  35. "_index": "pms",
  36. "_type": "product",
  37. "_id": "31",
  38. "_score": 3.8090763,
  39. "_source": {
  40. "subTitle": "2018夏季新品短袖T恤男HNTBJ2E080A 蓝灰花纹80 175/92A/L80A 蓝灰花纹80 175/92A/L",
  41. "name": "HLA海澜之家蓝灰花纹圆领针织布短袖T恤"
  42. }
  43. }
  44. ]
  45. }
  46. }

组合搜索

组合搜索,使用bool来进行组合,must表示同时满足,例如搜索subTitle字段中同时包含2018男生的文档;

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. { "match": { "subTitle": "2018" } },
  7. { "match": { "subTitle": "男生" } }
  8. ]
  9. }
  10. }
  11. }

组合搜索,should表示满足其中任意一个,搜索name字段中包含HLA或者海澜之家的文档

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. { "match": { "name": "HLA" } },
  7. { "match": { "name": "海澜之家" } }
  8. ]
  9. }
  10. }
  11. }

组合搜索,must_not表示不同时满足,搜索subTitle字段不同时包含移动 电信的文档

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must_not": [
  6. { "match": { "subTitle": "移动" } },
  7. { "match": { "subTitle": "电信" } }
  8. ]
  9. }
  10. }
  11. }

组合搜索,must和must_not配合,搜索name包含小米subTitle不包含电信的文档

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. { "match": { "name": "小米" } }
  7. ],
  8. "must_not": [
  9. { "match": { "subTitle": "电信" } }
  10. ]
  11. }
  12. }
  13. }

过滤搜索

使用filter来表示,比如获取price在600-1000之间的商品

  1. GET /pms/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": { "match_all": {} },
  6. "filter": {
  7. "range": {
  8. "price": {
  9. "gte": 600,
  10. "lte": 1000
  11. }
  12. }
  13. }
  14. }
  15. }
  16. }

搜索聚合

对搜索结果进行聚合,用aggs表示,类似sql的group by 。例如对brandName进行聚合,统计出brandName相同的数目

  1. GET /pms/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_brandName": {
  6. "terms": {
  7. "field": "brandName"
  8. }
  9. }
  10. }
  11. }
  1. {
  2. "took": 90,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": 11,
  12. "max_score": 0,
  13. "hits": []
  14. },
  15. "aggregations": {
  16. "group_by_brandName": {
  17. "doc_count_error_upper_bound": 0,
  18. "sum_other_doc_count": 0,
  19. "buckets": [
  20. {
  21. "key": "小米",
  22. "doc_count": 4
  23. },
  24. {
  25. "key": "海澜之家",
  26. "doc_count": 3
  27. },
  28. {
  29. "key": "NIKE",
  30. "doc_count": 2
  31. },
  32. {
  33. "key": "华为",
  34. "doc_count": 1
  35. },
  36. {
  37. "key": "苹果",
  38. "doc_count": 1
  39. }
  40. ]
  41. }
  42. }
  43. }

嵌套聚合,同时聚合brandName和price,计算出brandName相同的数目和price的平均值

  1. GET /pms/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_brandName": {
  6. "terms": {
  7. "field": "brandName"
  8. },
  9. "aggs": {
  10. "average_price": {
  11. "avg": {
  12. "field": "price"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }
  1. {
  2. "took": 123,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": 11,
  12. "max_score": 0,
  13. "hits": []
  14. },
  15. "aggregations": {
  16. "group_by_brandName": {
  17. "doc_count_error_upper_bound": 0,
  18. "sum_other_doc_count": 0,
  19. "buckets": [
  20. {
  21. "key": "小米",
  22. "doc_count": 4,
  23. "average_price": {
  24. "value": 2461.5
  25. }
  26. },
  27. {
  28. "key": "海澜之家",
  29. "doc_count": 3,
  30. "average_price": {
  31. "value": 88
  32. }
  33. },
  34. {
  35. "key": "NIKE",
  36. "doc_count": 2,
  37. "average_price": {
  38. "value": 434
  39. }
  40. },
  41. {
  42. "key": "华为",
  43. "doc_count": 1,
  44. "average_price": {
  45. "value": 3788
  46. }
  47. },
  48. {
  49. "key": "苹果",
  50. "doc_count": 1,
  51. "average_price": {
  52. "value": 5499
  53. }
  54. }
  55. ]
  56. }
  57. }
  58. }

对聚合搜索的结果进行排序

  1. GET /pms/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_brandName": {
  6. "terms": {
  7. "field": "brandName",
  8. "order": {
  9. "average_price": "desc"
  10. }
  11. },
  12. "aggs": {
  13. "average_price": {
  14. "avg": {
  15. "field": "price"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  1. {
  2. "took": 39,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": 11,
  12. "max_score": 0,
  13. "hits": []
  14. },
  15. "aggregations": {
  16. "group_by_brandName": {
  17. "doc_count_error_upper_bound": 0,
  18. "sum_other_doc_count": 0,
  19. "buckets": [
  20. {
  21. "key": "苹果",
  22. "doc_count": 1,
  23. "average_price": {
  24. "value": 5499
  25. }
  26. },
  27. {
  28. "key": "华为",
  29. "doc_count": 1,
  30. "average_price": {
  31. "value": 3788
  32. }
  33. },
  34. {
  35. "key": "小米",
  36. "doc_count": 4,
  37. "average_price": {
  38. "value": 2461.5
  39. }
  40. },
  41. {
  42. "key": "NIKE",
  43. "doc_count": 2,
  44. "average_price": {
  45. "value": 434
  46. }
  47. },
  48. {
  49. "key": "海澜之家",
  50. "doc_count": 3,
  51. "average_price": {
  52. "value": 88
  53. }
  54. }
  55. ]
  56. }
  57. }
  58. }

参考 https://mp.weixin.qq.com/s/cohWZy_eUOUqbmUxhXzzNA

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号