索引

创建索引

curl -XPUT http://localhost:9200/blog/article/1 -d '{
  "title": "New version of es!",
  "content": "...",
  "tags": [
    "announce",
    "es",
    "release"
  ]
}'

当然也可以通过如下命令创建

curl -XPUT http://localhost:9200/blog/

当索引存在的时候,结果会提示

{
    "error": {
        "root_cause": [
            {
                "type": "index_already_exists_exception",
                "reason": "index [blog/mwdQFFt9QTydOWX2V_0d8Q] already exists",
                "index_uuid": "mwdQFFt9QTydOWX2V_0d8Q",
                "index": "blog"
            }
        ],
        "type": "index_already_exists_exception",
        "reason": "index [blog/mwdQFFt9QTydOWX2V_0d8Q] already exists",
        "index_uuid": "mwdQFFt9QTydOWX2V_0d8Q",
        "index": "blog"
    },
    "status": 400
}

es的结果也是以json显示的,相关字段会有提示index already exists

在创建第一个文档的时候可能并不关心索引,如果索引blog不存在,es会默认自动创建该索引。

action.auto_create_index: -an*, +a*, -*
可以配置是否自动创建索引,eg,对于a开头的自动创建,an开头的不创建,其他索引也必须手动创建。

在创建索引的时候,可以通过settings指定相关参数,如

"settings": {
    "number_of_shards":
    "number_of_replicas":
}

删除索引

curl -XDELETE http://10.10.193.203:9200/blog2/

es对索引字段的类型存在自动检测,同时会对索引中未包含的字段自动加入到索引字段中,有时候这样是我们不想看到的。可以通过”dynamic”:”false”来关闭自动添加字段。

es中使用模式映射(schema mapping)定义索引结构。

索引文档index

PUT twitter/tweet/1
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}
# 修改某一版本文档
PUT twitter/tweet/1?version=1
{
    "message" : "elasticsearch now has versioning support, double cool!"
}

接受op_type参数,以下两者等价。

PUT twitter/tweet/1?op_type=create
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}
PUT twitter/tweet/1/_create
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

当不传入id时,默认生成id,并索引文档

POST twitter/tweet/
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

可以通过routing参数,设置路由,这样,可以让多个文档路由到相同的分片;依次,查询时也要设置路由参数,否则无法查询到。Note, issuing a get without the correct routing, will cause the document not to be fetched.

获取文档get

GET /twitter/tweet/1
curl -XGET "http://10.10.193.203:9200/twitter/tweet/1"

get默认会返回文档的source字段,除非增加参数_source=false

curl -XGET 'http://localhost:9200/twitter/tweet/1?_source=false'

从source字段中包含或删除

GET /twitter/tweet/2?_source_include=user&_source_exclude=message
GET /twitter/tweet/2?_source_include=user,message

Stored Field

PUT twitter
{
   "mappings": {
      "tweet": {
         "properties": {
            "counter": {
               "type": "integer",
               "store": false    #不存储类型
            },
            "tags": {
               "type": "keyword",
               "store": true    #存储类型
            }
         }
      }
   }
}
PUT twitter/tweet/1        #索引一个文档
{
    "counter" : 1,
    "tags" : ["red"]
}
GET twitter/tweet/1?stored_fields=tags,counter        #查询两个存储字段
# 结果只有tags字段返回,非stored字段将被查询忽略
{
   "_index": "twitter",
   "_type": "tweet",
   "_id": "1",
   "_version": 1,
   "found": true,
   "fields": {
      "tags": [
         "red"
      ]
   }
}

通过/{index}/{type}/{id}/_source直接获取source字段

GET /twitter/tweet/2/_source
# 也可以增加参数
GET /twitter/tweet/2/_source?_source_include=*.id&_source_exclude=entities'

文档删除

curl -XDELETE 'http://localhost:9200/twitter/tweet/1'
DELETE /twitter/tweet/1

同样受routing参数影响

文档更新

PUT test/type1/1
{
    "counter" : 1,
    "tags" : ["red"]
}
POST test/type1/1/_update
{
    "script" : {
        "inline": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}
结果
{
  "_index": "test",
  "_type": "type1",
  "_id": "1",
  "_version": 2,
  "found": true,
  "_source": {
    "counter": 5,
    "tags": [
      "red"
    ]
  }
}
POST test/type1/1/_update
{
    "script" : {
        "inline": "ctx._source.tags.add(params.tag)",
        "lang": "painless",
        "params" : {
            "tag" : "blue"
        }
    }
}
结果
{
  "_index": "test",
  "_type": "type1",
  "_id": "1",
  "_version": 3,
  "found": true,
  "_source": {
    "counter": 5,
    "tags": [
      "red",
      "blue"
    ]
  }
}

增加新字段

POST test/type1/1/_update
{
    "script" : "ctx._source.new_field = \"value_of_new_field\""
}

删除字段

POST test/type1/1/_update
{
    "script" : "ctx._source.remove(\"new_field\")"
}

将doc参数merge到文档1中

POST test/type1/1/_update
{
    "doc" : {
        "name" : "new_name"
    }
}

如果更新的文档不存在,可以插入

POST test/type1/1/_update
{
    "doc" : {
        "name" : "new_name"
    },
    "doc_as_upsert" : true
}

mget

GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_type" : "type1",
            "_id" : "1"
        },
        {
            "_index" : "test",
            "_type" : "type1",
            "_id" : "2"
        }
    ]
}
合并index参数
curl 'localhost:9200/test/_mget' -d '{
    "docs" : [
        {
            "_type" : "type1",
            "_id" : "1"
        },
        {
            "_type" : "type1",
            "_id" : "2"
        }
    ]
}'
合并type参数
curl 'localhost:9200/test/type1/_mget' -d '{
    "docs" : [
        {
            "_id" : "1"
        },
        {
            "_id" : "2"
        }
    ]
}'
合并id参数
curl 'localhost:9200/test/type/_mget' -d '{
    "ids" : ["1", "2"]
}'

当type参数为空,或者设置为_all的时候,将会返回满足id的第一条文档记录

mget和get类似,也可以设置_source字段的过滤

GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_type" : "type1",
            "_id" : "1",
            "_source" : true
        },
        {
            "_index" : "test",
            "_type" : "type1",
            "_id" : "1",
            "_source" : ["tags", "counter"]
        },
        {
            "_index" : "test",
            "_type" : "type1",
            "_id" : "1",
            "_source" : {
                "include": ["tags"],
                "exclude": ["name"]
            }
        }
    ]
}

查询

简单查询

query_string

GET bank/account/_search
{
  "query":{
  "query_string":{"query":"state:PA"}
  }
}

分页

在上述DSL中增加

"from": 1
  , "size": 3

返回字段

es5之前的版本stored_fields就叫做fields。如果未指定stored_fields,返回结果将返回_source字段。

"stored_fields":["account_number", "age", "state"]

查询DSL

match_all

GET bank/account/_search
{
  "query": {
    "match_all": {}
  }
}

全文查询 full text queries

在查询字符串执行操作前需要分析。

词项查询 term level queries

只针对倒排索引中的确切词(term)进行操作。经常被用在结构化数据结构,包括数字、日期、枚举等。

词条查询

包含改词条的文档,确切的、未经分析的词条。这里的包含,对于英文来说是空格分隔的自然词。address字段,包含avenue的。avenue在建立索引的时候已经变成了小写。

GET bank/account/_search
{
  "query": {
    "term": {
      "address": "avenue"
    }
  }
}
Java API
    QueryBuilder qb = termQuery(
        "address",    
        "avenue"   
    );

在term中可以增加boost,调节权重。在此例子中由于参与搜索的只有address一个匹配字段,所以跳转address的权重为10,相当于调整得分为原来的10倍。

"term": {
  "address": {
    "value": "avenue",
    "boost": 10
  }
}

多词条查询

在5.0后,不再支持terms直接查询以及terms下的注入minimum_match等参数,需要使用filter。

GET bank/account/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "terms": {
          "address": [
            "avenue",
            "street"
          ]
        }
      }
    }
  }
}

范围查询 Rang Query

GET _search
{
    "query": {
        "range" : {
            "age" : {
                "gte" : 10,
                "lte" : 20,
                "boost" : 2.0
            }
        }
    }
}

对于日期类型可以使用Date Math

"gte" : "now-1d/d",
"lt" :  "now/d"

存在查询 Exits Query

GET /_search
{
    "query": {
        "exists" : { "field" : "user" }
    }
}

前缀查询 Prefix Query

GET /_search
{ "query": {
    "prefix" : { "state" : "p" }
  }
}

通配符查询 Wildcard Query

GET /_search
{
    "query": {
        "wildcard" : { "city" : "*i*ey" }
    }
}

正则匹配 Regexp Query

详见官方文档

模糊查询 Fuzzy Query

将在接下来的版本中删除,使用match queries with fuzziness替代。
匹配方式,是使用编辑距离Levenstein distance

类型查询 Type Query

GET /_search
{
    "query": {
        "type" : {
            "value" : "account"
        }
    }
}

ID查询

GET /_search
{
    "query": {
        "ids" : {
            "type" : "account",
            "values" : ["1", "4", "100"]
        }
    }
}