Elasticsearch学习随笔与Scrapy中Elasticsearch的应用

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch学习随笔与Scrapy中Elasticsearch的应用

elasticsearch概念

集群: 一个或者多个节点组织在一起

节点: 一个节点是集群中的一个服务器,由一个名字来标识,默认是一个随机的漫画角色的名字

分片: 将索引划分为多份的能力,允许水平分割和扩展容量, 多个分片响应请求,提高性能和吞吐量

副本: 创建分片的一份货多份的能力,在一个节点失败其余节点可以顶上

elasticsearch中的index(索引),type(类型),documents(文档),fields

与mysql中的数据库,表,行,列一一对应

倒排索引

倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值得各记录的地址。由于不是由记录来确定属性值,而是有属性值来确定记录的位置,因而称为倒排索引,带有倒排索引的文件我们称为倒排索引文件,简称倒排文件。

es的文档、索引的CRUD操作

新建分片,副本数量
1# 新建分片,副本数量
 2PUT lagou
 3{
 4  "settings": {
 5    "index":{
 6        "number_of_shards":5,
 7        "number_of_replicas":1
 8    }
 9  }
10}
查看设置、修改设置、查看索引信息
1# 查看
 2GET lagou/_settings
 3GET .all/_settings
 4GET _settings
 5GET .kibana,lagou/_settings
 6
 7# 修改setting
 8PUT lagou/_settings
 9{
10       "number_of_replicas":2
11}
12
13# 索引信息
14GET _all
15GET lagou
新增文档
1# 新增文档
 2POST lagou/job
 3{
 4 "title":"python分布式爬虫开发",
 5 "salary_min":15000,
 6 "company":{
 7  "name":"百度",
 8  "company_addr":"北京软件园"
 9 },
10 "publish_date":"2017-4-16",
11 "comments":15
12}
13
14# 新增文档
15POST lagou/job/1
16{
17 "title":"python web开发",
18 "salary_min":18000,
19 "company":{
20  "name":"美团",
21  "company_addr":"北京软件园"
22 },
23 "publish_date":"2017-4-16",
24 "comments":20
25}
查看文档
1# 查看文档
2GET lagou/job/1
3GET lagou/job/1?_source
4GET lagou/job/1?_source=title
5GET lagou/job/1?_source=title,comments
修改文档(覆盖式)与指定修改
1# 修改文档(覆盖式)
 2PUT lagou/job/1
 3{
 4 "title":"python web开发",
 5 "salary_min":18000,
 6 "company":{
 7"city":"上海",
 8  "name":"美团",
 9  "company_addr":"北京软件园"
10 },
11 "publish_date":"2017-4-16",
12 "comments":201
13}
14
15# 修改(指定修改)
16POST lagou/job/1/_update
17{
18 "doc":{
19  "comments":20
20 }
21
22}
删除文档,类(无法删除),索引
1# 删除文档,类(无法删除),索引
2DELETE lagou/job/1
3DELETE lagou/job
4DELETE lagou

es的mget和bulk批量操作

mget操作实例
1GET _mget
 2{
 3  "docs":[
 4    {"_index":"testdb",
 5      "_type":"job1",
 6      "_id":1
 7    },
 8    {"_index":"testdb",
 9      "_type":"job1",
10      "_id":2
11    }
12  ]
13}
14
15GET testdb/_mget
16{
17  "docs":[
18    {
19      "_type":"job1",
20      "_id":1
21    },
22    {
23      "_type":"job1",
24      "_id":2
25    }
26  ]
27}
28
29GET testdb/job1/_mget
30{
31  "docs":[
32    {
33      "_id":1
34    },
35    {
36      "_id":2
37    }
38  ]
39}
40
41GET testdb/job1/_mget
42{
43  "ids":[1,2]
44}
bulk批量操作

批量导入可以合并多个操作,比如index,delete,update,create等,也可以帮助从一个索引导入到另一个索引。

1action_and_mete_data\n
2optional_source\n
3action_and_mete_data\n
4optional_source\n
5action_and_mete_data\n
6optional_source\n
7....

简单实例:

1POST _bulk
2{"index":{"_index":"lagou", "_type":"job", "_id":"1"}}
3{"title":"python web开发", "salary_min":18000, "company":{"city":"上海","name":"美团","company_addr":"北京软件园"}, "publish_date":"2017-4-16", "comments":20}
4{"index":{"_index":"lagou", "_type":"job2", "_id":"2"}}
5{"title":"python web flask开发", "salary_min":20000, "company":{"city":"北京","name":"阿里","company_addr":"北京软件园2"}, "publish_date":"2017-4-18", "comments":20}

其他实例:

1{"index":{"_index":"test","_type":"type1","_id":"1"}}
2{"field1":"value1"}
3{"delete":{"_index":"test","_type":"type1","_id":"2"}}
4{"create":{"_index":"test","_type":"type1","_id":"3"}}
5{"field1":"value3"}
6{"update":{"id":"1","_type":"type1","_index":"index1"}}
7{"doc":{"field2":"value2"}}

映射

创建索引的时候,可以预先定义字段的类型以及相关属性

es会根据json源数据的基础类型猜测你想要的字段映射,将输入的数据转变成可搜索的索引项,mapping就是我们自己定义的字段数据类型,同时告诉es如何索引数据以及是否可以被搜索

作用: 会让索引建立的更加细致和完善

类型: 静态映射和动态类型

内置类型

string类型: text,keyword

数字类型: long,integer,short,byte,double,float

日期类型: date

bool类型:boolean

binary类型: binary

复杂类型: object,nested

geo类型: geo-point, geo-shape

专业类型: ip, competion

映射实例
1PUT lagou
 2{
 3  "mappings":{
 4    "job":{
 5      "properties":{
 6        "title":{
 7          "type":"text"
 8        },
 9        "salary_min":{
10          "type":"integer"
11        },
12        "city":{
13          "type":"keyword"
14        },
15        "company":{
16          "properties":{
17            "name":{
18              "type":"text"
19            },
20            "company_addr":{
21              "type":"text"
22            },
23            "employee_count":{
24              "type":"integer"
25            }
26          }
27        },
28        "publish_date":{
29          "type":"date",
30          "format":"yyyy-MM-dd"
31        },
32        "comments":{
33          "type":"integer"
34        }
35      }
36    }
37  }
38}

插入实例:

1PUT lagou/job/2
 2{
 3  "title":"python分布式爬虫",
 4  "salary_min":15000,
 5  "city":"北京",
 6  "company":{
 7      "name":"百度",
 8      "company_addr":"北京",
 9      "employee_count":50
10  },
11  "publish_date":"2017-4-18",
12  "comments":15
13}

查询

基本查询: 使用es内置查询条件进行查询

组合查询: 把多个查询组合在一起进行复合查询

过滤: 查询同时,通过filter条件在不影响打分的情况下筛选数据

基础查询

先建立映射:

1PUT lagou
 2{
 3  "mappings":{
 4    "job":{
 5      "properties":{
 6        "title":{
 7          "store":true,
 8          "type":"text",
 9          "analyzer": "ik_max_word"
10        },
11        "company":{
12          "store":true,
13          "type": "keyword"
14        },
15        "desc":{
16          "type":"text"
17        },
18        "add_time":{
19          "type":"date",
20          "format":"yyyy-MM-dd"
21        },
22        "comments":{
23          "type":"integer"
24        }
25      }
26    }
27  }
28}

match查询(分词查询):

1GET lagou/job/_search
 2{
 3  "query":{
 4      "match":{
 5          "title":"python爬虫"
 6      }
 7  }
 8}
 9
10# 这里查询时会将python爬虫分为“python”和”爬虫”进行查询,包含这个分词结果的都会返回

term查询(全量查询):

1GET lagou/job/_search
 2{
 3  "query":{
 4      "term":{
 5          "title":"python爬虫"
 6      }
 7  }
 8}
 9
10# 将python爬虫直接进行全量查询,包含“python爬虫”的才会被返回回来,类似查询关键字

terms查询(全量查询):

1GET lagou/job/_search
 2{
 3  "query":{
 4      "terms":{
 5          "title":["python","系统","django"]
 6      }
 7  }
 8}
 9
10# 查询列表中包含的多个关键字,包含其中一个就返回回来

控制查询返回的数量:

1GET lagou/job/_search
 2{
 3  "query":{
 4      "match":{
 5          "title":"python"
 6      }
 7  },
 8  "from":0,
 9  "size":3
10}
11
12# from属性指从第几个开始
13# size指返回几条结果

返回所有查询结果:

1GET lagou/_search
2{
3  "query":{
4      "match_all":{}
5  }
6}

短语查询:

1GET lagou/job/_search
 2{
 3  "query":{
 4      "match_phrase":{
 5          "title":{
 6              "query":"python师",
 7              "slop":3
 8          }
 9      }
10  }
11}
12
13# 短语查询查询的是分词后“python”和“师”中间隔3个字以上(含3个字)的短语
14# slop 间隔的字符数

查询多个字段:

1GET lagou/job/_search
 2{
 3  "query":{
 4      "multi_match":{
 5          "query":"python",
 6          "fields":["title^3","desc"]
 7      }
 8  }
 9}
10
11# 查询title 和 desc 字段包含 python 的关键词文档
12# 其中 箭号+数字 表示权重, 上图表示 title 的 权重 是desc 的3倍

返回指定字段:

1GET lagou/job/_search
 2{
 3  "stored_fields":["title","company"],
 4  "query":{
 5      "match":{
 6          "title":"python"
 7
 8      }
 9  }
10}
11
12# 这里只返回 title company 两个字段
13# 需要注意的是 这里显示的字段需在映射时设置 store 为 true 默认为false

将查询结果进行排序:

1GET lagou/job/_search
 2{
 3  "query":{
 4      "match_all":{}
 5  },
 6  "sort":[{
 7      "comment":{
 8          "order":"asc" # 升序
 9      }
10  }]
11}

范围查询:

1GET lagou/job/_search
 2{
 3  "query":{
 4      "range":{
 5          "comment":{
 6              "gte":10,
 7              "lte":50,
 8              "boost":2.0
 9          }
10
11      }
12  }
13}
14
15# gte 大于等于  gt 大于
16# lte 小于等于  lt 小于

模糊查询:

1GET lagou/_search
 2{
 3  "query":{
 4      "wildcard":{
 5          "title":{
 6              "value":"pyth*n",
 7              "boost":2.0
 8          }
 9
10      }
11  }
12}
13# 这里的boost指权重

bool组合查询

bool查询包含以下四种:

1bool:{
2    "filter":[],  # 字段过滤,不参与打分
3    "must":[],    # 数组里的所有查询必须全部满足
4    "should":[],  # 数组里的所有查询满足一个就行
5    "must_not":[] # 数组里的所有查询必须全部不满足
6}

bool查询的简单实例

这里的每个例子都使用sql语句作为对照学习,加深理解。

数据插入:

1  POST lagou/testjob/_bulk
2  {"index":{"_id":1}}
3  {"salary":10, "title":"Python"}
4  {"index":{"_id":2}}
5  {"salary":20, "title":"Scrapy"}
6  {"index":{"_id":3}}
7  {"salary":30, "title":"Django"}
8  {"index":{"_id":4}}
9  {"salary":30, "title":"Elasticsearch"}

简单的过滤查询:

1select * from testjob where comments=20
1GET lagou/testjob/_search
 2{
 3    "query":{
 4        "bool":{
 5            "must":{
 6                "match_all":{}
 7            },
 8            "filter":{
 9                "match":{
10                    "salary":20
11                }
12            }
13        }
14    }
15}

同时可以指定多个值:

1GET lagou/testjob/_search
 2{
 3    "query":{
 4        "bool":{
 5            "must":{
 6                "match_all":{}
 7            },
 8            "filter":{
 9                "match":{
10                    "salary":[10,20]
11                }
12            }
13        }
14    }
15}

组合过滤查询:

1select * from testjob where (salary=20 or title=python) and (salary != 30)
1GET lagou/testjob/_search
 2{
 3    "query":{
 4        "bool":{
 5            "should":[
 6                {"term":{"salary":20}},
 7                {"term":{"title":"python"}}
 8            ],
 9            "must_not":{
10                "term":{
11                    "price":30
12                }
13            }
14        }
15    }
16}

嵌套查询:

1select * from testjob where title="Python" or (title="Elasticsearch" and salary=30)
1GET lagou/testjob/_search
 2{
 3    "query":{
 4        "bool":{
 5            "should":[
 6                {"term":{"salary":20}},
 7                {"bool":{
 8                    "must":[
 9                        {"term":{"title":"elasticsearch"}},
10                        {"term":{"salary":30}}
11                    ]
12                }
13        }
14    ]
15  }
16}
17}
过滤空和非空

先插入测试数据:

1POST lagou/testjob2/_bulk
 2{"index":{"_id":1}}
 3{"tags":["search"]}
 4{"index":{"_id":2}}
 5{"tags":["search","python"]}
 6{"index":{"_id":3}}
 7{"other_field":["some data"]}
 8{"index":{"_id":4}}
 9{"tags":null}
10{"index":{"_id":5}}
11{"tags":["search",null]}

处理null空值的方法:

1select tags from testjob2 where tags is not NULL
1GET lagou/testjob2/_search
 2{
 3    "query":{
 4        "bool":{
 5            "filter":{
 6                "exists":{
 7                    "field":"tags"
 8                }
 9            }
10        }
11    }
12}

查看分析器解析结果

使用ik_max_word分析器,会最大化的生成分词结果。

1# 查看分析器解析的结果
2GET _analyze
3{
4  "analyzer":"ik_max_word",
5  "text":"python网络"
6}

使用ik_max_word分析器,会最少的生成分词结果。

1# 查看分析器解析的结果
2GET _analyze
3{
4  "analyzer":"ik_smart",
5  "text":"python网络"
6}

Scrapy如何将数据存入elasticsearch

安装 elasticsearch-dsl
1pip install elasticsearch-dsl
提供一个bobby老师的pipline模板(此处代码有省略)

新建一份 models.py 文件,文件作用就是定义映射,之后运行代码就会生成索引。

1from datetime import datetime
 2from elaticsearch-dsl import DocType, Date, Nested, Boolean, analyzer, InnerObjectWrapper, Completion, Keyword, Text
 3from elaticsearch-dsl.connections import connections
 4connections.create_connection(hosts = ["localhost"])
 5class AticleType(DocType):
 6    title = Text(analyzer="ik_max_word")
 7
 8    class Meta:
 9        index = "jobbole"
10        doc_type = "article"
11
12if __name__ == '__main__':
13    AticleType.init()

在pipline中实现下面的类,完成。

1class ElasticsearchPipeline(object):
2    def process_item(self, item, spider):
3        article = AticleType()
4        article.title = item['title']
5
6        article.save()
7        return item
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
5月前
|
运维 监控 Java
探索Elasticsearch在Java环境下的全文检索应用实践
【6月更文挑战第30天】在大数据背景下,Elasticsearch作为分布式搜索分析引擎,因其扩展性和易用性备受青睐。本文指导在Java环境中集成Elasticsearch,涉及安装配置、使用RestHighLevelClient连接、索引与文档操作,如创建索引、插入文档及全文检索查询。此外,还讨论了高级查询、性能优化和故障排查,帮助开发者高效处理非结构化数据全文检索。
167 0
|
15天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
59 6
|
1月前
|
自然语言处理 Java 网络架构
elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
这篇文章是关于如何自定义Elasticsearch的ik分词器配置以满足特定的中文分词需求。
123 0
elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
|
2月前
|
机器学习/深度学习 存储 监控
Elasticsearch 在日志分析中的应用
【9月更文第2天】随着数字化转型的推进,日志数据的重要性日益凸显。日志不仅记录了系统的运行状态,还提供了宝贵的洞察,帮助企业改进产品质量、优化用户体验以及加强安全防护。Elasticsearch 作为一个分布式搜索和分析引擎,因其出色的性能和灵活性,成为了日志分析领域的首选工具之一。本文将探讨如何使用 Elasticsearch 作为日志分析平台的核心组件,并详细介绍 ELK(Elasticsearch, Logstash, Kibana)栈的搭建和配置流程。
263 4
|
10天前
|
存储 SQL 监控
|
10天前
|
自然语言处理 监控 数据可视化
|
1月前
|
JSON Java 网络架构
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
这篇文章介绍了如何使用Spring Boot整合REST方式来搭建和操作Elasticsearch服务。
121 4
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
|
16天前
|
数据采集 前端开发 中间件
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第26天】Python是一种强大的编程语言,在数据抓取和网络爬虫领域应用广泛。Scrapy作为高效灵活的爬虫框架,为开发者提供了强大的工具集。本文通过实战案例,详细解析Scrapy框架的应用与技巧,并附上示例代码。文章介绍了Scrapy的基本概念、创建项目、编写简单爬虫、高级特性和技巧等内容。
39 4
|
15天前
|
数据采集 中间件 API
在Scrapy爬虫中应用Crawlera进行反爬虫策略
在Scrapy爬虫中应用Crawlera进行反爬虫策略
|
1月前
|
人工智能
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
172 2