警告
elasticsearch 7.X 开始舍弃 type ,所以很多API会根据版本不同,而不同
elasticsearch 中的文档都是不允许被修改的,所有的修改操作都是 重建新的文档,把老的文档标记删除,增加版本号。这会造成很容易出现冲突。。
以全文 analyzed 字段排序会消耗大量的内存。
创建索引(用user表示索引)
put /user
{
"settings":{
"number_of_shards":3,
"number_of_replicas":1
}
}
修改索引
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
查询索引
/user get
删除索引
/user delete
创建索引字段
PUT /user/_mapping/_doc
{
"properties":{
"id":{
"type":"integer",
"index":"not_analyzed",
"store":true
},
"username":{
"type":"text",
"index":"analyzed",
"store":true,
"analyzer":"ik_max_word"
},
"password":{
"type":"text",
"index":"no",
"store":true
},
"email":{
"type":"text",
"index":"ik_max_word",
"store":true
}
}
}
插入/修改 文档(id自己指定)
PUT /{index}/{type}/{id}
{
"field": "value",
...
}
只插入,不修改 文档(id自己指定)
PUT /{index}/{type}/{id}?op_type=create
{
"field": "value",
...
}
PUT /{index}/{type}/{id}/_create
{
"field": "value",
...
}
插入文档 (id系统指定)
post /{index}/{type}
{
"field": "value",
...
}
取出文档(根据ID,全部字段)
GET /{index}/{type}/{id}?pretty
取出文档(根据ID,部分字段)
GET /{index}/{type}/{id}??_source=filed,filed
检查文档是否存在
curl -i -XHEAD http://localhost:9200/website/blog/123
删除文档
delete /{index}/{type}/{id}
解决并发修改(指定版本号,只有当前版本才能修改成功,其他版本修改失败)
PUT /{index}/{type}/{id}?version=1
{
"field": "value",
...
}
文档部分更新
POST /{index}/{type}/{id}/_update
{
"doc" : {
"tags" : [ "testing" ],
"views": 0
}
}
1.更新冲突
有可能在update设法重新索引之前,来自另一进程的请求修改了文档。
为了避免数据丢失,update API 在 检索 步骤时检索得到文档当前的 _version 号,并传递版本号到 重建索引 步骤的 index 请求。 如果另一个进程修改了处于检索和重新索引步骤之间的文档,那么 _version 号将不匹配,更新请求将会失败。
对于部分更新的很多使用场景,文档已经被改变也没有关系。 例如,如果两个进程都对页面访问量计数器进行递增操作,它们发生的先后顺序其实不太重要; 如果冲突发生了,我们唯一需要做的就是尝试再次更新。
这可以通过设置参数 retry_on_conflict 来自动完成, 这个参数规定了失败之前 update 应该重试的次数,它的默认值为 0 。
POST /{index}/{type}/{id}/_update?retry_on_conflict=5
{
"doc": {
"views": 0
}
}
取回多个文档
Elasticsearch 的速度已经很快了,但甚至能更快。 将多个请求合并成一个,避免单独处理每个请求花费的网络延时和开销。 如果你需要从 Elasticsearch 检索很多文档,那么使用 multi-get 或者 mget API 来将这些检索请求放在一个请求中,将比逐个文档请求更快地检索到全部文档
mget API 要求有一个 docs 数组作为参数,每个元素包含需要检索文档的元数据, 包括 _index 、 _type 和 _id 。如果你想检索一个或者多个特定的字段,那么你可以通过 _source 参数来指定这些字段的名字:
GET /_mget
{
"docs" : [
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website",
"_type" : "pageviews",
"_id" : 1,
"_source": "views"
}
]
}
相同索引或者type下时
GET /{index}/{type}/_mget
{
"docs" : [
{ "_id" : 2 },
{ "_type" : "pageviews", "_id" : 1 }
]
}
如果所有文档的 _index 和 _type 都是相同的,你可以只传一个 ids 数组,而不是整个 docs 数组:
GET /{index}/{type}/_mget
{
"ids" : [ "2", "1" ]
}
文档会被存储到哪一个分片中
shard = hash(routing) % number_of_primary_shards
routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到 余数
分页查询
GET /_search?size=5&from=5
GET /{index}/_search?size=5&from=5
GET /{index}/${type}/_search?size=5&from=5
查询映射结构
GET {index}/_mapping/{type} (7.x以下的版本)
GET {index}/_mapping (7.x 及以上的版本)
测试分词器
GET /_analyze
{
"analyzer": "standard",
"text": "Text to analyze"
}
搜索
空搜索
GET /_search
{}
分页
GET /_search
{
"from": 30,
"size": 10
}
filter(不需要评分的,效率高,5.X 被移除) and query(对结果需要评分的)
query:
GET /_search
{
"query": YOUR_QUERY_HERE
}
GET /_search
{
"query": {
"match_all": {}
}
}
{"query":{
"match": {
"name":"哈"
}
}
}
match:(只能使用一个filed)
如果你在一个全文字段上使用 match 查询,在执行查询前,它将用正确的分析器去分析查询字符串
{"query":{
"match": {
"name":"哈"
}
}
}
multi_match 查询
multi_match 查询可以在多个字段上执行相同的 match 查询:
{"query":{
"multi_match": {
"query":"哈2",
"fields":["name","category_name2"]
}
}
}
range 查询
range 查询找出那些落在指定区间内的数字或者时间:
{"query":{
"range": {
"price":{
"gte":110,
"lt": 1113
}
}
}
}
gt:大于
gte:大于等于
lt:小于
lte:小于等于
term 查询
term 查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串:如果文档内容被分词,然后使用term,是可能不能匹配到任何文档的
{"query":{
"term": {
"name":"哈"
}
}
}
terms 查询
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件:
{"query":{
"terms": {
"name":["哈","女"]
}
}
}
exists 查询和 missing 查询
exists 查询和 missing 查询被用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档。这与SQL中的 IS_NULL (missing) 和 NOT IS_NULL (exists) 在本质上具有共性:
{"query":{
"exists": {
"field":"name"
}
}
}
组合多查询:
must:文档 必须 匹配这些条件才能被包含进来。
must_not:文档 必须不 匹配这些条件才能被包含进来。
should:如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。
filter:必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
{"query":{
"bool": {
"must":{"match":{"name":"哈哈"}}
}
}
}
{"query":{
"bool": {
"must":{"match":{"name":"女装"}},
"should":[
{"match":{"name":"裤子"}},
{"range":{"price":{"gte":111}}}
]
}
}
}
增加带过滤器(filtering)的查询
如果我们不想因为文档的price而影响得分,可以用 filter 语句来重写前面的例子
{"query":{
"bool": {
"must":{"match":{"name":"女装"}},
"should":[{"match":{"name":"裤子"}}],
"filter":{"range":{"price":{"gte":110}}}
}
}
}
constant_score 查询
尽管没有 bool 查询使用这么频繁,constant_score 查询也是你工具箱里有用的查询工具。它将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下。
{
"constant_score": {
"filter": {
"term": { "category": "ebooks" }
}
}
}
验证查询
查询可以变得非常的复杂,尤其和不同的分析器与不同的字段映射结合时,理解起来就有点困难了。不过 validate-query API 可以用来验证查询是否合法。
GET /${index}/${type}/_validate/query?explain
按照字段的值排序
可以使用 sort 参数进行实现:
{
"query":{
"bool": {
"must":{
"match":{
"name":"女装"
}
}
}
},
"sort":{"update_time":"desc"}
}
多重排序:
{
"query":{
"bool": {
"must":{
"match":{
"name":"女装"
}
}
}
},
"sort":[
{"price":{"order":"desc"}},
{"id":{"order":"asc"}}
]
}
精确值查找
当进行精确值查找时, 我们会使用过滤器(filters)。过滤器很重要,因为它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。我们会在本章后面的 过滤器缓存 中讨论过滤器的性能优势,不过现在只要记住:请尽可能多的使用过滤式查询。
term 查询数字
我们首先来看最为常用的 term 查询, 可以用它处理数字(numbers)、布尔值(Booleans)、日期(dates)以及文本(text)。
布尔过滤器
一个 bool 过滤器由三部分组成:
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
}
}