elasticsearch基础知识:
基础知识:
1 集群
主节点不涉及文档级别的变更或搜索 只负责索引的变更 删除 和 集群节点的加入和删除
技术上来说,一个主分片最大能够存储 Integer.MAX_VALUE - 128 个文档
索引是指向一个或多个物理分片的逻辑命名空间 分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点中
2 索引->复数词为indices或indexes
3 一个文档路由到分片的公式: shard = hash(routing) % number_of_primary_shards routing是一个可变值,默认是文档的_id ,也可以设置成一个自定义的值
4 es支持域类型
字符串
string(es5.x不再支持) string类型在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和keyword类型替代
text 当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,
字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合
keyword 适用于索引结构化的字段,比如email地址、主机名、状态码和标签。keyword类型的字段只能通过精确值搜索到
整数
byte -128~127
short -32768~32767
integer -2的31次方~2的31次方-1
long -2的63次方~2的63次方-1
浮点数
doule 64位双精度IEEE 754浮点类型
float 32位单精度IEEE 754浮点类型
half_float 16位半精度IEEE 754浮点类型
scaled_float 缩放类型的的浮点数
对于float、half_float和scaled_float,-0.0和+0.0是不同的值,使用term查询查找-0.0不会匹配+0.0,同样range查询中上边界是-0.0不会匹配+0.0,
下边界是+0.0不会匹配-0.0。其中scaled_float,比如价格只需要精确到分,price为57.34的字段缩放因子为100,
存起来就是5734 优先考虑使用带缩放因子的scaled_float浮点类型。
布尔型 boolean
日期 date
二进制类型 binary
二进制字段是指用base64来表示索引中存储的二进制数据,可用来存储二进制形式的数据,例如图像。默认情况下,该类型的字段只存储不索引。二进制类型只支持index_name属性
数组类型 array
在ElasticSearch中,没有专门的数组(Array)数据类型,但是,在默认情况下,任意一个字段都可以包含0或多个值,这意味着每个字段默认都是数组类型,
只不过,数组类型的各个元素值的数据类型必须相同
在同一个数组中,数组元素的数据类型是相同的,ElasticSearch不支持元素为多个数据类型:[ 10, “some string” ],常用的数组类型是
1 字符数组: [ “one”, “two” ]
2 整数数组: productid:[ 1, 2 ]
3 对象(文档)数组: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }],
ElasticSearch内部把对象数组展开为 {“user.name”: [“Mary”, “John”], “user.age”: [12,10]}
对象类型 object
嵌套类型 nested
地理坐标类型 geo_point
地理地图 geo_shape
iP类型 ip
ip类型的字段用于存储IPv4或者IPv6的地址
范围类型 completion
令牌计数类型 token_count
附件类型 attachment
抽取类型 percolator
5 不会被索引的值 空值
"null_value": null,
"empty_array": [],
"array_with_null_value": [ null ]
6
1 启动
./bin/elasticsearch -d(后台启动)
2 curl请求 curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
VERB 适当的 HTTP 方法 或 谓词 : GET`、 `POST`、 `PUT`、 `HEAD 或者 `DELETE`。
PROTOCOLhttp 或者 https`(如果你在 Elasticsearch 前面有一个 `https 代理)
HOST Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。
PORT 运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。
PATH API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING 任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)
BODY 一个 JSON 格式的请求体 (如果请求需要的话)
3 常用请求:
请求过程一些重要参数
version
1 外部版本号 /website/blog/2?version=5&version_type=external
2 内部版本号 /website/blog/2?version=5&version=1
upsert
在更新文档时 如果文档不存在 则先新建 以免在不知道文档字段是否存在时 修改字段值报错
retry_on_conflict 规定了失败之前 update 应该重试的次数,它的默认值为 0 例 /website/pageviews/1/_update?retry_on_conflict=5
consistency(一致性)
值为 one 只要主分片状态 ok 就允许执行_写_操作
all 必须要主分片和所有副本分片的状态没问题才允许执行_写_操作
quorum 默认值为 quorum,即大多数的分片副本状态没问题就允许执行_写_操作 int( (primary + number_of_replicas) / 2 ) + 1
timeout
ES的默认超时时间是1分钟
took 执行整个搜索请求耗费了多少毫秒
explain 获取查询失败OR成功详细的数据信息
type 字段的数据类型,例如 string 或 date
index 字段是否应当被当成全文来搜索( analyzed ),或被当成一个准确的值( not_analyzed ),还是完全不可被搜索( no )
analyzer 确定在索引和搜索时全文字段使用的 analyzer
查询参数
term 精确搜索 注意字段是否analyer
配置参数
_source可以被禁用
PUT /my_index
{
"mappings": {
"my_type": {
"_source": {
"enabled": false
}
}
}
}
_all禁用
PUT /my_index/_mapping/my_type
{
"my_type": {
"_all": { "enabled": false }
}
}
include_in_all 设置来逐个控制字段是否要包含在 _all 字段中 默认是true 在一个对象(或根对象)上设置 `include_in_all 可以修改这个对象中的所有字段的默认行为
PUT /my_index/my_type/_mapping
{
"my_type": {
"include_in_all": false, //设置全部
"properties": {
"title": {
"type": "string",
"include_in_all": true //单独设置字段 设为true _all搜索将会搜索到
},
}
}
}
1 搜索
查询结构
{
QUERY_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
{
QUERY_NAME: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
复合查询
{
"bool": {
"must": { "match": { "tweet": "elasticsearch" }},
"must_not": { "match": { "name": "mary" }},
"should": { "match": { "tweet": "full text" }},
"filter": { "range": { "age" : { "gt" : 30 }} }
}
}
空查询 or matcha_all查询
{
"query": {
"match_all": {}
}
}
match查询
在一个全文字段上使用 match 查询,在执行查询前,它将用正确的分析器去分析查询字符串
如果在一个精确值的字段上使用它, 例如数字、日期、布尔或者一个 not_analyzed 字符串字段,那么它将会精确匹配给定的值
{ "match": { "tweet": "About Search" }}
短语搜索 or match_phrase查询
curl -X GET "localhost:9200/megacorp/employee/_search" -H 'Content-Type: application/json' -d'
{
"query" : {
"match_phrase" : { //精确搜索
"about" : "rock climbing"
}
}
}
'
multi_match查询
在多个字段执行相同查询
{
"multi_match": {
"query": "full text search",
"fields": [ "title", "body" ]
}
}
range查询
{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
term精确查询
term 查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
{ "term": { "public": true }}
{ "term": { "tag": "full_text" }}
terms查询
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件
{ "terms": { "tag": [ "search", "full_text", "nosql" ] }}
exists和missing查询
exists 查询和 missing 查询被用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档。这与SQL中的 IS_NULL (missing) 和 NOT IS_NULL (exists) 在本质上具有共性
{
"exists": {
"field": "title"
}
}
bool组合查询
must 文档 必须 匹配这些条件才能被包含进来
must not 文档 必须不 匹配这些条件才能被包含进来
should 如果满足这些语句中的任意语句,将增加_score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分
filter 必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"bool": {
"must": [
{ "range": { "date": { "gte": "2014-01-01" }}},
{ "range": { "price": { "lte": 29.99 }}}
],
"must_not": [
{ "term": { "category": "ebooks" }}
]
}
}
}
}
constant_score查询
它将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下
可以使用它来取代只有 filter 语句的 bool 查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助
{
"constant_score": {
"filter": {
"term": { "category": "ebooks" }
}
}
}
验证查询
curl -X GET "localhost:9200/gb/tweet/_validate/query" -H 'Content-Type: application/json' -d'
{
"query": {
"tweet" : {
"match" : "really powerful"
}
}
}
'
sort排序
"sort": {
"dates": { //日期排序
"order": "asc",
"mode": "min" //对于数字OR日期来说 值可以为min 、 max 、 avg 或是 sum模式排序
}
}
请看 多字段映射 实例
注意(重要)
如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但,如果存在至少一条 must 语句,
则对 should 语句的匹配没有要求。换而言之 如果有must should的条件是否满足不是必须 如果没有must
条件, should的条件必须满足一条
普通搜索
Query-string
搜到一条: curl -X GET "localhost:9200/megacorp/employee/1"
搜索所有last_name为Smith: curl -X GET "localhost:9200/megacorp/employee/_search?q=last_name:Smith"
DSl
curl -X POST "localhost:9200/megacorp/employee/_search" -H 'Content-Type: application/json' -d'
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": { //过滤match的查询
"range" : {
"age" : { "gt" : 30 }
}
}
}
}
}'
查询指定的字段
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {}},
"_source": [ "title", "created" ]
或者
}
'
或者禁用_source
{
"mappings": {
"my_type": {
"_source": {
"enabled": false
}
}
}
}
高亮搜索
curl -X GET "localhost:9200/megacorp/employee/_search" -H 'Content-Type: application/json' -d'
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
'
聚合搜索
搜索每种爱好的平均年龄
{
"aggs": {
"all_test": { //随意命名
"terms": {
"field": "interests.keyword"
},
"aggs": {
"agetest": { //随意命名
"avg": {
"field": "age"
}
}
}
}
}
}
获取多个文档的搜索
curl -X GET "localhost:9200/_mget" -H 'Content-Type: application/json' -d'
{
"docs" : [
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website",
"_type" : "pageviews",
"_id" : 1,
"_source": "views"
}
]
或
"ids" : ["2", "1"]
}
'
游标查询
GET /old_index/_search?scroll=1m //保持游标查询1分钟
{
"query": { "match_all": {}},
"sort" : ["_doc"], //关键字 _doc 是最有效的排序顺序。
"size": 1000
}
再次查询 需要传递scroll_id 以此类推
GET /_search/scroll
{
"scroll": "1m",
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}
2 变更文档(修正)
更新整个文档
curl -X PUT "localhost:9200/website/blog/123" -H 'Content-Type: application/json' -d'
{
"title": "My first blog entry",
"text": "I am starting to get the hang of this...",
"date": "2014/01/02"
}
'
局部更新文档
curl -X POST "localhost:9200/website/blog/1/_update" -H 'Content-Type: application/json' -d'
{
"doc" : {
"tags" : [ "testing" ],
"views": 0
}
}
'
脚本更新文档
curl -X POST "localhost:9200/website/blog/1/_update" -H 'Content-Type: application/json' -d'
{
"script" : "ctx._source.views+=1"
}
'
脚本删除文档
curl -X POST "localhost:9200/website/blog/1/_update" -H 'Content-Type: application/json' -d'
{
"script" : "ctx.op = ctx._source.views == count ? \u0027delete\u0027 : \u0027none\u0027",
"params" : {
"count": 1
}
}
'
创建文档
1 文档已经存在 则提示错误 如果不存在 则创建新文档
PUT /website/blog/123?op_type=create
PUT /website/blog/123/_create
删除文档
curl -X DELETE "localhost:9200/website/blog/123"
批量操作
注释:
一个好的批量大小在开始处理后所占用的物理大小约为 5-15 MB
每个子请求都是独立执行,因此某个子请求的失败不会对其他子请求的成功与否造成影响。 如果其中任何子请求失败,最顶层的 error 标志被设置为 true ,并且在相应的请求报告出错误明细
格式
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
action 必须是以下选项之一:
create 如果文档不存在,那么就创建它。
index 创建一个新文档或者替换一个现有的文档
update 部分更新一个文档。delete 动作不能有请求体
delete 删除一个文档。详情请见 删除文档。
metadata 应该 指定被索引、创建、更新或者删除的文档的 _index 、 _type 和 _id 。
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"} }
3 索引操作
索引配置
禁止自动创建索引
action.auto_create_index:false
设置使删除只限于特定名称指向的数据, 而不允许通过指定 _all 或通配符来删除指定索引库
action.destructive_requires_name: true
创建索引
PUT /my_index
{
"settings": { ... any settings ... },
"mappings": {
"type_one": { ... any mappings ... },
"type_two": { ... any mappings ... },
}
}
修改索引配置
PUT /my_temp_index/_settings
{
"number_of_replicas": 1
}
删除索引
DELETE /my_index
DELETE /index_one,index_two
DELETE /index_*
DELETE /_all //删除所有索引
索引别名
_alias 用于单个操作
_aliases 用于执行多个原子级操作
PUT /my_index_v1/_alias/my_index 设置别名my_index指向my_index_v1
查看别名指向的索引
GET /*/_alias/my_index
查看索引指向的别名
GET /my_index_v1/_alias/*
POST /_aliases 一个别名可以指向多个索引
{
"actions": [
{ "remove": { "index": "my_index_v1", "alias": "my_index" }},
{ "add": { "index": "my_index_v2", "alias": "my_index" }}
]
}
11 计算集群中文档的数量:
curl -i -XGET "http://localhost:9200/_count?pretty" -d '
{
"query":{
"match_all": {}
}
}
'
20 映射 mapping 和 分析 analysis
映射和分析参数
dynamic 可以用在根 object 或任何 object 类型的字段上 针对新字段希望抛出异常还是自动映射类型
true 动态添加新的字段--缺省
false 忽略新的字段
strict 如果遇到新字段抛出异常
date_detection 日期检测可以通过在根对象上设置 date_detection 为 false 来关闭
PUT /my_index
{
"mappings": {
"my_type": {
"date_detection": false
}
}
}
分析器执行三大过程
字符过滤器 字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 `and`。
分词器 字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。
token过滤器 词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick ),
删除词条(例如, 像 a`, `and`, `the 等无用词),或者增加词条(例如,像 jump 和 leap 这种同义词)。
字符串 "Set the shape to semi-transparent by calling set_trans(5)"
内置分析器
标准分析器 标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。
它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写
set, the, shape, to, semi, transparent, by, calling, set_trans, 5
简单分析器 简单分析器在任何不是字母的地方分隔文本,将词条小写
set, the, shape, to, semi, transparent, by, calling, set, trans
空格分析器 空格分析器在空格的地方划分文本。
Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
语言分析器 特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语 分析器附带了一组英语无用词(常用单词,例如 and 或者 the
它们对相关性没有多少影响),它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的词干
set, shape, semi, transpar, call, set_tran, 5
创建分析器
1 依赖标准分析器创建
curl -X PUT "localhost:9200/spanish_docs" -H 'Content-Type: application/json' -d'
{
"settings": {
"analysis": {
"analyzer": {
"es_std": {
"type": "standard", //依赖标准分析器创建的分析器
"stopwords": "_spanish_" //停用词
}
}
}
}
}
'
使用创建的分析器
curl -X GET "localhost:9200/spanish_docs/_analyze?analyzer=es_std" -H 'Content-Type: application/json' -d'
El veloz zorro marrón
'
2 自定义分析器
PUT /my_index
{
"settings" : {
"analysis": {
"char_filter": { ... custom character filters ... },
"tokenizer": { ... custom tokenizers ... },
"filter": { ... custom token filters ... },
"analyzer": { ... custom analyzers ... }
}
}
}
curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{
"settings": {
"analysis": {
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": [ "&=> and "]
}},
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": [ "the", "a" ]
}},
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": [ "html_strip", "&_to_and" ],
"tokenizer": "standard",
"filter": [ "lowercase", "my_stopwords" ]
}}
}}}
'
查询分析
curl -X GET "localhost:9200/_analyze" -H 'Content-Type: application/json' -d'
{
"analyzer": "standard",
"text": "Text to analyze"
}
'
GET /my_store/_analyze
{
"field": "productID",
"text": "XHDK-A-1293-#fJ3"
}
分析参数解析
type 设置字段类型
index 控制怎样索引字符串
analyzed 首先分析字符串,然后索引它。换句话说,以全文索引这个域
not_analyzed 索引这个域,所以它能够被搜索,但索引的是精确值。不会对它进行分析
no 不索引这个域。这个域不会被搜索到
analyzer 属性指定在搜索和索引时使用的分析器
例
{
"tweet": {
"type": "text", 字符
"analyzer": "english" //语言分析器
}
}
分析和映射创建
{
"mappings": {
"test": { //类型 根对象
"properties" : {
"tt": { //字段
"type": "text",
"analyzer" : "english"
},
"date" : { //字段
"type" : "date"
},
"user": {
"type": "object", //对象
"properties": {
"id": { "type": "text" },
"gender": { "type": "text" },
"name": {
"type": "object", //嵌套对象
"properties": {
"full": { "type": "text" },
"first": { "type": "text" },
"last": { "type": "text" }
}
}
}
}
}
}
}
}
更新映射(不能修改已存在的映射)
curl -X PUT "localhost:9200/gb/_mapping/test" -H 'Content-Type: application/json' -d'
{
"properties" : {
"tag" : { //字段
"type" : "string",
"index": "not_analyzed"
}
}
}
'
动态映射
curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{
"mappings": {
"my_type": {
"dynamic": "strict", //strict 如果遇到新字段抛出异常 true 动态添加新的字段--缺省
//false 忽略新的字段
"properties": {
"title": { "type": "string"},
"stash": {
"type": "object",
"dynamic": true
}
}
}
}
}
'
多字段映射 针对字段用做搜索和排序
"tweet": {
"type": "string",
"analyzer": "english",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
多字段排序
以全文 analyzed 字段排序会消耗大量的内存 如tweet字段
curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"tweet": "elasticsearch"
}
},
"sort": "tweet.raw"
}
'
注意
其他简单类型(例如 long , double , date 等)也接受 index 参数,但有意义的值只有 no 和 not_analyzed ,
因为它们永远不会被分析
30 集群
查看集群健康 curl -X GET "localhost:9200/_cluster/health?pretty"
status 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
green 所有的主分片和副本分片都正常运行
yellow 所有的主分片都正常运行,但不是所有的副本分片都正常运行。
red 有主分片没能正常运行。
设置分片和副本集
{
"settings": {
"numbers_of_shards": 3, //主分片
"number_of_replicas": 1 //每个分片的副本集
}
}
检索词频率/反向文档频率, TF/IDF
检索词频率 检索词在该字段出现的频率?出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高
反向文档频率 每个检索词在索引中出现的频率?频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低
字段长度准则 字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大
悲观并发控制
这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。
乐观并发控制
Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据、或者将相关情况报告给用户。