一、写入
先来一个简单的官方例子,插入的参数为-XPUT
,插入一条记录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
curl -XPUT
'http://localhost:9200/test/users/1'
-d '{
"user"
:
"test"
,
"post_date"
:
"2009-11-15T14:12:12"
,
"message"
:
"Elastic Search"
}'
{
"_index"
:
"test"
,
"_type"
:
"users"
,
"_id"
:
"1"
,
"_version"
: 2,
"_shards"
: {
"total"
: 2,
"successful"
: 1,
"failed"
: 0
},
"created"
:
false
}
|
从上面的这个例子中,可以看出ES的http的服务的默认端口9200,后面的/test/users/1
是这条记录的索引部分,体现了它的RESTful风格
这三级目录分布对应了_index,
_type,
_id
实际上ES上存放的所有的记录都只能通过三级目录的方式找到
-
_id
字段可以是数字也可以是字符串。在执行上面的命令时ES会自动创建这些索引 -
-d
后面跟上了要插入的json格式的记录 -
-XPUT
表明这是插入一条数据,ES中叫创建一个索引 -
_version
字段,表明了当前记录的版本号,当你想这个索引重新put一条记录时,版本号会自动加一
二、删除
删除的http请求参数为-XDELETE
,通过下面的命令可以删除这条记录:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
curl -XDELETE
'http://localhost:9200/test/users/1?pretty'
{
"found"
:
true
,
"_index"
:
"test"
,
"_type"
:
"users"
,
"_id"
:
"1"
,
"_version"
: 3,
"_shards"
: {
"total"
: 2,
"successful"
: 1,
"failed"
: 0
}
}
|
删除这条记录的时候,_verison
也会自动加一的。
三、查询
创建了一个索引后,可以通过下面的方式查询(参数-XGET
)出来
1
2
3
4
5
6
7
8
9
10
11
12
13
|
curl -XGET
'http://localhost:9200/test/users/1?pretty'
{
"_index"
:
"test"
,
"_type"
:
"users"
,
"_id"
:
"1"
,
"_version"
: 1,
"found"
:
true
,
"_source"
: {
"user"
:
"test"
,
"post_date"
:
"2009-11-15T14:12:12"
,
"message"
:
"Elastic Search"
}
}
|
执行上面的查询命令,可以等到下面的结果,exists
表示是否有查询结果,_source
字段是查询到的记录。
查询的时候,可以将_type
设置成为_all
,ES就会返回在_index
下所有type中,第一个匹配_id
的记录,还可以通过参数对返回结果继续控制,
用fields选取返回的字段,用pretty控制返回的json格式是否更阅读友好
1
2
3
4
5
6
7
8
9
10
11
12
|
curl -XGET
'http://localhost:9200/test/users/1?fields=message,user&pretty=true'
{
"_index"
:
"test"
,
"_type"
:
"users"
,
"_id"
:
"1"
,
"_version"
: 3,
"found"
:
true
,
"fields"
: {
"message"
: [
"Elastic Search"
],
"user"
: [
"test"
]
}
}
|
format=yaml
可以设置输入格式为YAML
1
2
3
4
5
6
7
8
9
10
11
12
|
curl -XGET
'http://localhost:9200/test/users/1?fields=message,user&format=yaml'
---
_index:
"test"
_type:
"users"
_id:
"1"
_version: 1
found:
true
fields:
message:
-
"Elastic Search"
user:
-
"test"
|
当然ES还支持一次查询多组记录,即multi get,在URI中是使用关键字_mget,具体可以参考ES的文档multi get。
四、更新
ES同样支持更新,但是更新的方式是通过一个提供的脚本进行的。
ES的做法是,通过index找到相应的存放记录的节点,然后执行脚本,执行完之后,返回新的索引。实际上执行的是一个get和reindex的过程,在这个过程中,通过versioning来控制没有其它的更新操作(这个功能是0.19后可用的)。具体实现的原理应该和elasticsearch Versioning相关。
get,reindex的含义是,ES先取出这条记录,然后根据新数据生成新记录,然后在把新记录放回到ES中(并不会覆盖老的记录)。
首先创建一条记录
1
2
3
4
|
curl -XPUT localhost:9200
/test/type1/1
-d '{
"counter"
: 1,
"tags"
: [
"red"
]
}'
|
将counter的值加4
1
2
3
4
5
6
|
curl -XPOST
'localhost:9200/test/type1/1/_update'
-d '{
"script"
:
"ctx._source.counter += count"
,
"params"
: {
"count"
: 4
}
}'
|
也可以添加一个tag的值
1
2
3
4
5
6
|
curl -XPOST
'localhost:9200/test/type1/1/_update'
-d '{
"script"
:
"ctx._source.tags += tag"
,
"params"
: {
"tag"
:
"blue"
}
}'
|
现在还支持upsert功能,即在更新的时候,如果记录没有这个key,则插入这个key,下面是一个例子,如果没有counter
字段,则插入该字段:
1
2
3
4
5
6
7
8
9
|
curl -XPOST
'localhost:9200/test/type1/1/_update'
-d '{
"script"
:
"ctx._source.counter += count"
,
"params"
: {
"count"
: 4
},
"upsert"
: {
"counter"
: 1
}
}'
|
关于update还有其它很多功能,可以参考ES的API update
五、搜索
elasticsearch的名字里面有一个search,那么主要功能也是search了。
es的search有两种形式,一是通过URI,二是通过Requst Body。通过URI查询,即将查询的语句放入到请求的url中,例如:
1
|
curl -XGET
'http://localhost:9200/twitter/tweet/_search?q=user:kimchy'
|
第二种方式,即在查询的请求中加入一个doc
1
2
3
4
5
|
curl -XGET
'http://localhost:9200/twitter/tweet/_search'
-d '{
"query"
: {
"term"
: {
"user"
:
"kimchy"
}
}
}'
|
query body的定义可以查看query DSL 另外两种查询方式都可以带参数,参数的含义参考URI Request和Request Body。
ES的搜索功能是可以跨index和type的,例如下面这几条命令
1
2
3
4
5
|
curl -XGET
'http://localhost:9200/twitter/_search?q=user:kimchy'
curl -XGET
'http://localhost:9200/twitter/tweet,user/_search?q=user:kimchy'
curl -XGET
'http://localhost:9200/kimchy,elasticsearch/tweet/_search?q=tag:wow'
curl -XGET
'http://localhost:9200/_all/tweet/\_search?q=tag:wow'
curl -XGET
'http://localhost:9200/\_search?q=tag:wow'
|
第一条是在所有的twitter
这个index下的所有type中查找,第二条是在tweet,user
这两个type中查找,第三条是在kimchy,elasticsearch
这两个index的tweet
这个type中查找,第四条使用了_all
关键字,是在所有的index的tweet
的type中查找,第五条更暴力,在所有的index和type中查找。
查找还有其它的很多选项,sort,高亮,选取返回记录的域Fields,还可以对返回的域使用一个脚本进行计算script Fields,或者对返回结果继续统计Facets,Facets的内容比较多,它支持关键词统计,范围内统计,直方图式统计,日期的直方图式统计,过滤,查询,还有记录地理位置距离的统计geo distance。 支持名字过滤Named Filters。 定义搜索类型Search Type 。例如什么Query And Fetch,Query Then Fetch。 索引加速的功能Index Boost,可以让某一个索引的权重大于另外一个。 保持上次检索的环境了结果Scroll。保留每一个命中的score值Explain。 设置命中的min_score。保留版本号Version。
Search的参数很多,我也没有一一看,不过果然是名字里面有个search,对检索的各种场景都有支持。
当然还支持多个查询multi search,例如下面这个例子
1
2
3
4
5
6
7
8
9
|
cat
requests
{
"index"
:
"test"
}
{
"query"
: {
"match_all"
: {}},
"from"
: 0,
"size"
: 10}
{
"index"
:
"test"
,
"search_type"
:
"count"
}
{
"query"
: {
"match_all"
: {}}}
{}
{
"query"
: {
"match_all"
: {}}}
$ curl -XGET localhost:9200
/_msearch
--data-binary @requests;
echo
|
六、DSL
1、match
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
curl -XGET
'localhost:9200/test/_search?pretty'
-d'{
"_source"
: [
"title"
,
"allnum"
],
"query"
: {
"match"
: {
"title"
:
"地铁跑酷"
}
}
}'
{
"took"
: 2,
"timed_out"
:
false
,
"_shards"
: {
"total"
: 5,
"successful"
: 5,
"failed"
: 0
},
"hits"
: {
"total"
: 1,
"max_score"
: 6.692047,
"hits"
: [ {
"_index"
:
"test"
,
"_type"
:
"external"
,
"_id"
:
"AVicbl1W9iJMapPz5wea"
,
"_score"
: 6.692047,
"_source"
: {
"title"
:
"地铁跑酷"
,
"allnum"
: 104541
}
} ]
}
}
|
显示指定字段,匹配关键字
结果格式
-
took
– 搜索用的毫秒 -
timed_out
– 搜索超时时间 -
_shards
– 搜索了多少个片段 成功搜索多少个 失败了多少个 -
hits
– 搜索的返回结果集 -
hits.total
– 结果的总数 -
hits.hits
– 实际搜索返回的数组 -
_score
andmax_score
- ignore these fields for now
一旦es搜索返回给你 该链接就断开了 es并不会想MySQL之类的 一直维护一个连接
更多限制条件的搜素
1
2
3
4
5
6
7
8
9
|
curl -XGET
'localhost:9200/test/_search?pretty'
-d'{
"from"
: 0,
"size"
: 1,
"_source"
: [
"title"
,
"allnum"
],
"query"
: {
"match"
: {
"title"
:
"地铁跑酷"
}
},
"sort"
: {
"allnum"
: {
"order"
:
"desc"
}}
}'
|
2、使用should
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
curl -XGET
'localhost:9200/test/_search?pretty'
-d'{
"from"
: 0,
"size"
: 2,
"_source"
: [
"title"
,
"allnum"
],
"query"
: {
"bool"
: {
"should"
: [
{
"match"
: {
"title"
:
"地铁跑酷"
} },
{
"match"
: {
"title"
:
"星猫跑酷"
} }
]
}
},
"sort"
: {
"allnum"
: {
"order"
:
"desc"
}}
}'
|
3、使用must/must not
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
curl -XGET
'localhost:9200/test/_search?pretty'
-d'{
"from"
: 0,
"size"
: 2,
"_source"
: [
"title"
,
"allnum"
],
"query"
: {
"bool"
: {
"must"
: [
{
"match"
: {
"title"
:
"地铁跑酷"
} },
{
"match"
: {
"title"
:
"星猫跑酷"
} }
]
}
},
"sort"
: {
"allnum"
: {
"order"
:
"desc"
}}
}'
|
当然 must /should/must not 可以联合起来使用
4、过滤器
1
2
3
4
5
6
7
8
9
10
|
curl -XPOST
'localhost:9200/test/_search?pretty'
-d'{
"query"
: {
"filtered"
: {
"query"
: {
"match_all"
: {}
},
"filter"
: {
"range"
: {
"allumn"
: {
"gte"
: 20000,
"lte"
: 30000 } } } }
}
}'
|
5、聚合
1
2
3
4
5
6
7
|
curl -XPOST
'localhost:9200/test/_search?pretty'
-d'{
"size"
: 0,
"aggs"
: {
"group_by_state"
: {
"terms"
: {
"field"
:
"state"
} }
}
}'
|
6、terms 过滤
1
2
3
4
5
6
7
8
9
10
|
curl -XPOST
'localhost:9200/test/_search?pretty'
-d'{
"query"
: {
"terms"
: {
"status"
: [
304,
302
]
}
}
}
|
7、range 过滤
1
2
3
4
5
6
7
8
9
|
curl -XPOST
'localhost:9200/test/_search?pretty'
-d'{
"query"
: {
"range"
: {
"allnum"
: {
"gt"
: 1
}
}
}
}
|
范围操作符包含:
-
gt :: 大于
-
gte:: 大于等于
-
lt :: 小于
-
lte:: 小于等于
8、exists 和 missing 过滤
exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件
1
2
3
4
5
|
{
"exists"
: {
"field"
:
"title"
}
}
|
9、bool 过滤
bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
- must :: 多个查询条件的完全匹配,相当于 and。
- must_not :: 多个查询条件的相反匹配,相当于 not。
- should :: 至少有一个查询条件匹配, 相当于 or。
这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:
1
2
3
4
5
6
7
8
9
10
|
{
"bool"
: {
"must"
: {
"term"
: {
"folder"
:
"inbox"
}},
"must_not"
: {
"term"
: {
"tag"
:
"spam"
}},
"should"
: [
{
"term"
: {
"starred"
:
true
}},
{
"term"
: {
"unread"
:
true
}}
]
}
}
|
七、中文分词
创建索引
1
|
curl -XPUT http:
//localhost
:9200
/index
|
创建映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
curl -XPOST http:
//localhost
:9200
/index/fulltext/_mapping
-d'
{
"fulltext"
: {
"_all"
: {
"analyzer"
:
"ik_max_word"
,
"search_analyzer"
:
"ik_max_word"
,
"term_vector"
:
"no"
,
"store"
:
"false"
},
"properties"
: {
"content"
: {
"type"
:
"string"
,
"store"
:
"no"
,
"term_vector"
:
"with_positions_offsets"
,
"analyzer"
:
"ik_max_word"
,
"search_analyzer"
:
"ik_max_word"
,
"include_in_all"
:
"true"
,
"boost"
: 8
}
}
}
}'
|
为索引添加一些内容
1
2
3
4
5
6
7
8
9
10
11
12
|
curl -XPOST http:
//localhost
:9200
/index/fulltext/1
-d'
{
"content"
:
"美国留给伊拉克的是个烂摊子吗"
}
'
curl -XPOST http:
//localhost
:9200
/index/fulltext/2
-d'
{
"content"
:
"公安部:各地校车将享最高路权"
}
'
curl -XPOST http:
//localhost
:9200
/index/fulltext/3
-d'
{
"content"
:
"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"
}
'
curl -XPOST http:
//localhost
:9200
/index/fulltext/4
-d'
{
"content"
:
"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
'
|
进行查询
1
2
3
4
5
6
7
8
9
10
11
12
|
curl -XPOST http:
//localhost
:9200
/index/fulltext/_search
-d'
{
"query"
: {
"term"
: {
"content"
:
"中国"
}},
"highlight"
: {
"pre_tags"
: [
"<tag1>"
,
"<tag2>"
],
"post_tags"
: [
"</tag1>"
,
"</tag2>"
],
"fields"
: {
"content"
: {}
}
}
}
'
|
参考:http://www.cnblogs.com/chenpingzhao/p/6067350.html