seq搜索引擎优化至少包括那几步?(开源ElasticsearchType类型Document可以分组吗?(一)(组图))

优采云 发布时间: 2022-02-01 04:15

  seq搜索引擎优化至少包括那几步?(开源ElasticsearchType类型Document可以分组吗?(一)(组图))

  文章目录

  前言一、基本概念全文搜索是最常见的需求,开源的Elasticsearch(以下简称Elastic)是目前全文搜索引擎的首选。它可以快速存储、搜索和分析海量数据。Wikipedia、Stack Overflow、Github 都使用它。底层 Elastic 是开源库 Lucene。但是,你不能直接使用Lucene,你必须自己编写代码来调用它的接口。Elastic 是 Lucene 的一个包,提供开箱即用的 REST API 操作接口。1. Node 节点和 Cluster 集群

  Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器都可以运行多个 Elastic 实例。

  单个 Elastic 实例称为节点。一组节点形成一个集群。

  2. 索引索引

  Elastic 索引所有字段并在处理后将它们写入倒排索引。查找数据时,直接查找索引。

  因此,Elastic 数据管理的顶层单元称为 Index。它是单个数据库的同义词。每个索引(即数据库)的名称必须是小写的。

  下面的命令可以查看当前节点的所有索引。

  获取 /_mapping?pretty=true

  

  3. 文档

  索引中的单个记录称为文档。许多文档形成一个索引。

  文档以 JSON 格式表示,以下是一个示例。

  {

"user": "张三",

"title": "工程师",

"desc": "数据库管理"

}

  同一个Index中的文档不要求结构(scheme)相同,但最好保持相同,有利于提高搜索效率。

  4. 类型

  可以对文档进行分组。例如,在天气指数中,它们可以按城市(北京和上海)或按气候(晴天和雨天)分组。这种分组称为Type,它是一个用于过滤Documents的虚拟逻辑分组。

  不同的类型应该有相似的模式,例如,id 字段不能是一组中的字符串,而另一组中不能是数值。这是与关系数据库表的区别。具有完全不同属性的数据(例如产品和日志)应该存储为两个索引,而不是一个索引中的两种类型(尽管可以这样做)。

  以下命令可以列出每个索引中收录的类型。(与上面的截图相同)

  获取 /_mapping?pretty=true

  按照计划,Elastic 6.x 版本只允许每个 Index 收录一个 Type,而 7.x 版本将彻底移除 Type。

  5. 逻辑比较

  上面提到的集群、节点、索引、类型、文档、分片(底层封装)和映射是什么?

  如何区分和比较非关系型数据库elasticsearch和关系型数据库,elasticsearch是面向文档的

  如下:关系型数据库和elasticsearch的客观对比!

  关系型数据库 非关系型数据库

  数据库数据库

  指数

  桌子

  类型(版本 7 已完全弃用)

  行

  文档

  字段列

  场地

  Elasticsearch(集群)可以收录多个索引(数据库),每个索引可以收录多个类型(表),每个类型收录多个文档(行),每个文档收录多个字段(列表)。

  6. 物理设计

  Elasticsearch在后台将每个索引分成多个shard,每个shard可以在集群中不同的服务器之间迁移。

  集群的默认名称是 elasticsearch。

  

  一个集群至少有一个节点,一个节点就是一个elasticsearch进程。一个节点可以有多个索引。默认情况下,如果创建索引,索引将由 5 个分片(primary shards,也称为主分片)组成。是的,每个主分片都会有一个副本(副本分片,也称为分配分片)

  

  索引分为多个shard,每个shard就是一个Lucene索引,所以一个elasticsearch索引是由多个Lucene索引组成的。因为elasticsearch使用Lucene作为底层。

  二、ES 命令风格

  一种软件架构风格,而不是标准,它只是提供一组设计原则和约束,主要用于与客户端和服务器交互的软件。基于这种风格设计的软件可以更简洁、更有层次、更容易实现缓存等机制。

  基本 RESTFUL 命令说明:

  methodurl地址说明

  放

  本地主机:9200/index_name/type_name/document_id

  创建文档(指定文档 ID)

  邮政

  本地主机:9200/index_name/type_name

  创建文档(随机文档 ID)

  邮政

  本地主机:9200/index_name/type_name/document_id/_update

  修改文档

  删除

  本地主机:9200/index_name/type_name/document_id

  删除文件

  得到

  本地主机:9200/index_name/type_name/document_id

  按文档id查询文档

  邮政

  本地主机:9200/index_name/type_name/document_id/_search

  查询所有文件

  PUT:一般创建索引,类型,文档 POST:添加数据,创建索引,类型,查询 DELETE:删除索引,文档 GET:查询 三、 创建和删除索引 index 创建索引索引

  放置/天气

  相当于

  curl -X PUT 'localhost:9200/天气'

  服务器返回一个带有确认字段的 JSON 对象,表明操作成功。

  

  然后,发出删除请求以删除索引。

  删除/天气

  相当于

  curl -X DELETE 'localhost:9200/天气'

  

  四、Tokenizer 使用与学习

  elasticsearch的查询是先通过tokenizer对单词进行分词,然后使用倒排索引匹配查询。

  1. 理论研究

  分词:就是将一段中文或者其他的一段分割成关键词,当我们搜索的时候,elasticsearch tokenizer会对自己的信息进行分词,对数据库或者索引库中的数据进行分词,然后执行一个匹配操作,默认的中文分词是将每个字符都当作一个词来对待,例如“我爱冯凡丽”会分为“我”、“爱”、“冯”、“凡”、“李”,这显然是不符合要求的,所以我们需要安装中文分词器ik来解决这个问题。

  ES默认分词是英文分词,对中文分词不太支持。如果要使用中文,推荐使用ik tokenizer!所以我们需要安装ik中文分词。

  IK提供了两种分词算法:ik_smart和ik_max_word,其中ik_mart是最小分词,ik_max_word是最新粒度分词!我们将在一段时间内测试!

  安装在第一篇博客中已经介绍过了,传送门:elasticsearch学习一:理解ES,版本之间的对应关系。安装 elasticsearch、kibana、head 插件、elasticsearch-ik 分词器。

  2. 用 kibana 测试

  ik_mart 是最少细分的

  

  ik_max_word 是最新的粒度划分,它穷尽了词库的可能性。

  

  输入超喜欢冯安辰java

  

  发现问题:风安辰被分开了,

  你需要的这种词,你需要将它添加到我们的分词器的字典中!

  ik tokenizer 添加了自己的配置!

  ik分词器自定义配置,我写了一篇博客:elasticsearch学习之三:elasticsearch-ik分词器的自定义配置分词内容

  设置好后再次执行:

  

  以后需要自己配置的分词可以在自己定义的dic文件中配置!五、数据操作1. 创建索引 创建索引方法1,简单创建索引

  PUT/索引名称创建索引方式2、创建索引并添加数据,字段类型系统默认给出

  该方法会直接创建索引名称、类型、id,并添加数据。

  PUT /索引名/~类型名~/文档id

{请求体}

  *敏*感*词*

  PUT /test1/type1/1

{

"name": "冯安晨",

"age": 18

}

  这样,index、type、id创建完成后,就添加了一条数据。

  

  创建索引方法3、创建索引并指定字段类型

  创建索引,指定类型名称,指定字段类型

  PUT /test2

{

"mappings": {

"type2": {

"properties": {

"name": {

"type": "text"

},

"age": {

"type": "long"

},

"birthday": {

"type": "date"

}

}

}

}

}

  

  2. 字段类型摘要

  那么上面的name字段就不需要指定类型了,毕竟我们的关系数据库需要指定类型!!

  3. 查看规则信息

  那就是看一下上面命令创建的细节

  获取命令

  GET /test1 : 查看索引信息

  如果我们自己的文档字段没有指定,那么ES会给我们默认的配置字段类型!就是上面的test1索引,没有指定字段类型,所以ES默认指定类型。

  

  4. 系统命令

  通过elasticsearch命令查看ES的各种信息!通过

  获取_猫/

  获取大量关于ES的最新信息!

  GET _cat/indices/?v:查看索引情况

  

  其他命令。

  

  5 添加数据

  默认指定数据类型

  PUT /fenganchen/user/1

{

"name": "冯凡利",

"age": 18,

"desc": "一顿操作猛如虎,一看工资2500",

"tags": ["技术宅", "温暖", "直男"]

}

  6. 修改数据 PUT 修改(不推荐)

  修改类似于add,但是这个修改类似于overwrite,如果缺少某个字段,则某个字段消失

  查看 GET /fenganchen/user/1(如下所述)

  

  修订

  PUT /fenganchen/user/1

{

"name": "冯凡利123",

"age": 18,

"desc": "一顿操作猛如虎,一看工资2500",

"tags": ["技术宅", "温暖", "直男"]

}

  _version 表示被修改的次数

  

  查看确认

  获取 /fenganchen/user/1

  

  湾。_update 修改(推荐)修改

  POST fenganchen/user/1/_update

{

"doc": {

"name": "冯凡利java"

}

}

  

  2. 查看

  

  7. 删除7. 简单查询 GET fenganchen/user/1

  

  简单的条件查询

  GET /fenganchen/user/_search?q=name:冯凡利 (报错,还未找到原因)

GET /fenganchen/user/_search?q=age:18

  

  

  8.向复杂查询添加更多数据

  PUT /fenganchen/user/2

{

"name": "张三",

"age": 17,

"desc": "法外狂徒张三",

"tags": ["技术宅", "温暖", "渣男"]

}

PUT /fenganchen/user/3

{

"name": "李四",

"age": 30,

"desc": "mmp 不知怎么形容了",

"tags": ["靓女", "旅游", "唱歌"]

}

  查询关键字:查询

  match关键字:match,这里有很多选项,比如:match_all:匹配所有,bool:返回一个布尔值,exists:存在等等。

  GET fenganchen/user/_search

{

"query": {

"match": {

"name": "冯凡利"

}

}

}

  

  3. 再添加一条数据,方便查询和测试:

  PUT /fenganchen/user/4

{

"name": "冯凡利前端",

"age": 3,

"desc": "一顿操作猛如虎,一看工资2500",

"tags": ["技术宅", "温暖", "直男"]

}

  再次查询:如下图

  Hits:包括索引和文档信息、查询结果总数、查询到的具体文档

  max_score:最大分数,是下面数据中最大的匹配分数值,也是最合适的

  _score:可以用来判断谁更符合结果,每个数据都有这个属性

  _source:数据对象信息关键字。

  

  9 筛选结果

  不想显示这么多字段,只想显示name和desc字段,可以使用数据对象信息关键字:_source来限制显示字段。

  GET fenganchen/user/_search

{

"query": {

"match": {

"name": "冯凡利"

}

},

"_source": ["name", "desc"]

}

  

  后面我们会用java来操作es,这里所有的方法和对象都是key:这个key也是hits、score等关键字。

  10. 排序

  GET fenganchen/user/_search

{

"query": {

"match": {

"name": "冯凡利"

}

},

"sort": [

{

"age": {

"order": "asc"

}

}

]

}

  

  11.分页查询

  GET fenganchen/user/_search

{

"query": {

"match": {

"name": "冯凡利"

}

},

"sort": [

{

"age": {

"order": "desc"

}

}

],

"from": 0,

"size": 1

}

  

  from:从第一条数据开始

  size:返回多少条数据(单页数据)

  数据下标还是从 0 开始,和所有学过的数据结构一样!

  /搜索/{当前}/{页面大小}

  12. 布尔查询必须(and),必须满足所有条件,类似于:where id=1 and name=xxx

  GET fengfanli/user/_search

{

"query": {

"bool": {

"must": [

{

"match": {

"name": "冯凡利"

}

},

{

"match": {

"age": "18"

}

}

]

}

}

}

  

  should(or),必须满足所有条件,类似于: where id=1 orname=xxx

  GET fenganchen/user/_search

{

"query": {

"bool": {

"should": [

{

"match": {

"name": "冯凡利"

}

},

{

"match": {

"age": "18"

}

}

]

}

}

}

  

  **must_not(not)**,必须满足所有条件,类似于: where id != 1

  GET fenganchen/user/_search

{

"query": {

"bool": {

"must_not": [

{

"match": {

"age": 3

}

}

]

}

}

}

  

  13.过滤常见匹配查询

  任何收录风范里字符串的东西都会被找到

  GET fenganchen/user/_search

{

"query": {

"bool": {

"must": [

{

"match": {

"name": "冯凡利"

}

}

]

}

}

}

  

  添加过滤器,过滤器

  filter关键字过滤查询的数据。

  GET fenganchen/user/_search

{

"query": {

"bool": {

"must": [

{

"match": {

"name": "冯凡利"

}

}

],

"filter": {

"range": {

"age": {

"gt": 3

}

}

}

}

}

}

  上面的语句是对查询语句进行过滤,过滤掉年龄大于3的数据

  

  14. 个空格匹配多个条件

  匹配关键字空间

  多个条件,以空格分隔

  只要隐藏其中一个结果,就能查出

  这时候通过_score分数就可以做出一个基本的判断了。

  以下查询语句的含义:在tags字段中找到male和technical的数据并进行查询

  GET fenganchen/user/_search

{

"query": {

"match": {

"tags": "男 技术"

}

}

}

  

  15. 词条精确查询 i。术语分析

  词条查询是通过倒排索引指定词条的过程直接搜索的!

  

  关于分词:

  ii. 两类文字关键词详解

  分词器不能使用两种类型的文本关键字

  文本类型:可分段

  关键字类型:不能分段

  首先创建索引并指定属性规则,如下:

  一个。版本 6 创建索引并指定规则

  elasticsearch 6.X必须指定创建索引的类型,feng_type是索引的类型名

  ```json

PUT testdb

{

"mappings": {

"feng_type": {

"properties": {

"name": {

"type": "text"

},

"desc": {

"type": "keyword"

}

}

}

}

}

```

  

  湾。版本 7 创建索引并指定规则

  elasticsearch 7.x 不需要指定类型来创建索引,因为版本7弃用了类型关键词(这里我就不演示了,我用的是6.4. 2 版本在这里。)

  ```json

PUT testdb

{

"mappings": {

"properties": {

"name": {

"type": "text"

},

"desc": {

"type": "keyword"

}

}

}

}

```

  C。添加数据

  ```json

PUT testdb/feng_type/1

{

"name": "冯凡利java name",

"desc": "冯凡利java desc"

}

PUT testdb/feng_type/2

{

"name": "冯凡利java name",

"desc": "冯凡利java desc2"

}

```

添加文档 1

  

  添加文档 2

  

  d。elasticsearch-head的google插件,查看testdb索引数据

  

  e. elasticsearch-head 的 Google 插件,参见 testdb 映射规则

  索引情况,可以查看索引的设置详情,以及映射映射规则包括类型和属性。

  可以看到,name 属性是 text 类型,而 desc 是关键字类型。

  

  F。默认标记器测试:关键字

  KeywordAnalyzer 将整个输入视为单个词汇单元,以促进特定类型文本的索引和检索。使用 关键词 标记器为邮政编码和地址等文本信息创建索引项非常方便。

  使用默认的关键字tokenizer进行分词,(比如说ik tokenizer是中文tokenizer),这里可以看出没有分析

  

  G。默认标记器测试:标准

  英文的处理能力和StopAnalyzer一样,支持中文的方法是分词。它将词汇单元转换为小写并删除停用词和标点符号。

  使用默认的标准分词器进行分词,见这里分析

  

  H。term 准确查找文本类型

  

  一世。term 查找确切的关键字类型

  

  

  j. 总结 h 和 i 的检验

  在 testdb 索引中:

  名称字段是文本类型,

  desc 字段是关键字类型。

  但是,当 term 精确搜索它们时,它会发现:

  在查找文本类型的名称字段时,只需收录它,即文本类型可以被分词器解释。在查找关键字类型的 desc 字段时,必须完全收录,即关键字类型将整个输入匹配为单个词法单元,由分词器解释。16. 多词精确匹配 a. 添加多数

  PUT testdb/feng_type/3

{

"t1": "22",

"t2": "2020-4-6"

}

PUT testdb/feng_type/4

{

"t1": "33",

"t2": "2020-4-7"

}

  

  

  湾。查看 elasticsearch-head 的谷歌插件,查看 testdb 索引数据和映射规则。索引数据

  

  映射规则

  

  C。词条精确查询

  

@​​>

  17. Highlight 高亮关键字:highlight

  GET fenganchen/user/_search

{

"query": {

"match": {

"name": "冯凡利"

}

},

"highlight": {

"fields": {

"name": {}

}

}

}

  

  自定义搜索突出显示

  GET fenganchen/user/_search

{

"query": {

"match": {

"name": "冯凡利"

}

},

"highlight": {

"pre_tags": "<p class=&#39;key style=&#39;color:red&#39;>",

"post_tags": "",

"fields": {

"name": {}

}

}

}

</p>

  

  这些mysql也可以做,但是mysql的效率比较低

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线