elasticsearch学习笔记整理(含下面总结的面试题)

elasticsearch是一个全文检索搜索引擎

Elasticsearch是一个基于Lucene的搜索服务器

ES可以做全文检索、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)。

es是不能使用root用户进行启动的,要新创建一个用户才行
创建用户:useradd qianfeng
设置密码:passwd qianfeng

早期es的结构

image

需要注意:Type类型,在Elasticsearch6.x的版本中已经被标记为废弃状态,在Elasticsearch7的版本中,已经被彻底移除。数据直接存储于Index,因此Index可以类比于关系型数据库中的数据库或者表的概念。

为了便于安装后期的操作以及效果展示,推荐安装head插件。(以下为head插件安装之后的效果图)

image

我们可以创建索引,同时制定分片数和副本数。

image

主分片和副分片图形展示

image

# 在一个没有索引的空集群中运行如上查询,将返回这些信息:

curl -X GET http://qianfeng01:9200/_cluster/health // qianfeng01表示第一个node节点的名称。连接es集群的时候,随便找一台节点就能连接上整个es集群。

创建索引

curl -X PUT http://qianfeng01:9200/bigdata2 // 创建名称为bigdata2的索引

查看索引中的所有数据

curl -X GET "http://qianfeng01:9200/route_test/_search?pretty" // pretty表示以格式化的方式进行数据的展示

指定id为c

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/route_test/_doc/c?routing=key1&refresh" -d '{"data":"C"}' // -H携带请求头-d表示指定后面要发送的数据,refresh表示能够尽快的将这条数据序列化出来

查看索引名为route_test的分片情况

curl -X GET "http://qianfeng01:9200/_cat/shards/route_test?v" // v表示显示列名

动态修改副本因子

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_settings -d '{"number_of_replicas":3}' // _settings表示设置配置信息

查看所有索引

curl -X GET "http://qianfeng01:9200/_cat/indices?v // _cat表示查看信息 indices表示索引

查看某个索引的具体配置信息

curl -X GET "http://qianfeng01:9200/bigdata // 查看名称为bigdata索引的配置信息

删除索引

curl -X DELETE "http://qianfeng01:9200/bigdata // 删除名称为bigdata的索引

创建文档

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_doc -d '{"title":"java","content","java 从入门到入土"}' // 向索引bigdata中插入一条文档,_doc表示文档

批量添加文档

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_bulk -d
'
{"title":"java","content","java 从入门到入土"}
{"title":"php","content","世界最好的语言"}
'
#使用读取文件的方式添加文档

curl -H "Content-Type: application/json" -X POST "http://qianfeng01:9200/bigdata/_bulk" --data-binary "@data.json"

修改文档

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_doc/101 -d '{"title":"java"}' // 修改101的数据,有则修改,没有就创建
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_doc/101/_update -d '{"title":"java"}' // 修改101的数据,只修改title字段,其他字段不修改

删除文档

curl -X DELETE "http://qianfeng01:9200/bigdata/_doc/101 // 删除docid为101的文档

检索文档

curl -X GET "http://qianfeng01:9200/bigdata/_doc/101?pretty // 查找docid为101的文档

检索title中包含HDFS的文档

curl -X GET "http://qianfeng01:9200/test/_search?q=title:HDFS&pretty"

检索title中包含HDFS的文档,只显示title和text两列,如果某条数据没有text列,就不进行展示

curl -X GET "http://qianfeng01:9200/test/_search?q=title:HDFS&_source=title,text&pretty"

分页查询

curl -X GET "http://qianfeng01:9200/test/_search?from=1&size=2&pretty"

批量检索

curl -H "Content-Type:application/json" -X GET "http://qianfeng01:9200/_mget?
pretty" -d \
'
{
"docs": [
		{
			"_index": "bigdata",
			"_id": "1",
			"_source": "name,age"
		},
		{
			"_index": "test",
			"_id": "1",
			"_source": "name"
		}
	]
}
'

指定路由的方式插入文档 routing=key1 这个key1可以随便写

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/route_test/_doc/c?routing=key1&refresh" -d '{"data":"C"}'

也就是说比方我再来一条数据,同样指定了 routing=key1,那么这条数据也会保存到相同的分片当中

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/route_test/_doc/d?routing=key1&refresh" -d '{"data":"Cc"}'

自定义routing后会导致一个问题:docid不再全局唯一!此时就需要自己手动去维护docid了。比如说我们可以通过java代码的方式进行单独的处理。

如果自定义了routing字段的话,一般doc的增删改查操作都要加上routing参数以保证一致性。为此,
Elasticsearch 7以上的版本中,在mapping中提供了一个选项("required": true),可以强制检查doc的
增删改查操作是否添加了routing参数,如果没有添加就会报错。

解决自定义路由产生的数据倾斜
shard_num = (hash(_rounting) + hash(_id) % routing_partition_size) % num_primary_shards

在同一个节点上面创建副本是没有任何意义的,创建副本主要的目的就是为了保证高可用性的。
比如我一共有3台机子,3个节点。创建好了N个主分片,创建副分片的数量只能是3-1个,因为要部署到不同的机子上面,如果创建的副分片的数量多余机子的数量,那么多余出来的是没有任何意义的。这个时候我们会看到集群的状态变成了yellow了。
索引创建完成之后,我们是可以再次修改副分片的数量的,但是主分片的数量是不能修改的,修改的话是会报错的。

Mapping类比于关系型数据库中的Schema,表结构,创建完索引之后,我们可以对表结构进行设置。
mapping可以定义index(索引)下面字段的名称和字段的类型

curl -X GET "http://qianfeng01:9200/bigdata/_mapping?pretty"
{
  "bigdata" : {
    "mappings" : {
      "properties" : {
        "content" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "date" : {
          "type" : "date",
          "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
        },
        "description" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "text" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

创建完索引的时候,可以对mapping的dynamic参数进行设置
true:动态映射, 动态映射,新增的一条文档可以被索引,可以搜索到。新增的字段也可以被索引,可以被搜索到,Mapping也会同步更新。
false:自定义映射,自定义映射,新增的一条文档可以被索引,可以被搜索到。文档中已经被定义到Mapping中的字段可以被索引,新增的字段无法被索引,将会被丢弃。
也就是说使用命令的方式是能够查询出新增的字段的,但是在head插件的页面上是看不到新增的字段的。
strict:数据写入直接出错

copy_to 将该字段的值复制到目标字段中,该字段不会出现在source中,只用来搜索

curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/my_index2" -d \
' // 将first_name和last_name字段的值赋值给full_name
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text",
        "copy_to": "full_name"
      },
      "last_name": {
        "type": "text",
        "copy_to": "full_name"
      },
      "full_name": {
        "type": "text"
      }
    }
  }
}
'

直接通过id查询是不显示full_name的。可以通过下面的方式进行查询

curl -H "Content-Type:application/json" -X GET "http://qianfeng01:9200/my_index2/_doc/1?pretty" -d \
'{
  "query": {
    "match": {
      **"full_name": "John Smith"**
    }
  }
}'

显示结果中也是不包含full_name字段的,只是用来进行组合查询用的。

index属性控制当前字段是否被索引,默认值为true,即这条消息可以被索引。false表示不被索引。

curl -H "Content-Type: application/json" -X PUT "http://qianfeng01:9200/my_index3" -d \
'
{
  "mappings": {
    "properties": {
      "idcard": {
        "type": "text",
        "index": false // 指定text字段不能被索引
      }
    }
  }
}
'

查看Mapping信息

curl -X GET "http://qianfeng01:9200/my_index3/_mapping?pretty"

在head插件中,高亮颜色的是主分片,暗淡一点的是副分片。

总结:要给面试官说出

elasticsearch是一个全文检索搜索引擎

Elasticsearch是一个基于Lucene的搜索服务器

ES可以做全文检索、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)。

主分片、副分片

索引创建完了之后,我们是不能够修改主分片的数量,但是可以修改副分片的数量。

索引里面包含文档,文档里面包含字段

添加文档的时候可以一条条添加,也可以批量添加,也可以使用读取配置文件的方式添加。

修改文档的时候和添加文档的时候使用的命令是一样的,说白了就是有那个字段就修改,没有就相当于是添加操作。

可以使用指定routing=key1 的方式来使得两条记录都能够插入到相同的主分片中。

创建完索引之后,我们可以对表结构进行设置。我们可以指定mapping可以定义index(索引)下面字段的名称和字段的类型。

创建完索引的时候,可以对mapping的dynamic参数进行设置

true:动态映射, 动态映射,新增的一条文档可以被索引,可以搜索到。新增的字段也可以被索引,可以被搜索到,Mapping也会同步更新。
false:自定义映射,自定义映射,新增的一条文档可以被索引,可以被搜索到。文档中已经被定义到Mapping中的字段可以被索引,新增的字段无法被索引,将会被丢弃。也就是说使用命令的方式是能够查询出新增的字段的,但是在head插件的页面上是看不到新增的字段的。
strict:数据写入直接出错。

copy_to 将该字段的值复制到目标字段中,该字段不会出现在source中,只用来搜索。

mapping中的index属性控制当前字段是否被索引,默认值为true,即这条消息可以被索引。false表示不被索引。

ES聚合查询(面试有被问到)

range terms interval max min等等

posted on 2024-09-12 15:31  ~码铃薯~  阅读(13)  评论(0编辑  收藏  举报

导航