概述
Elasticsearch是一种面向文档内存型搜索引擎,存储的数据类型为json,类似mango的nosql,它不仅仅只是存储还会索引文档中的内容,来便于全局搜素。
ES与关系型数据库的对比:
关系型数据库 | 数据库 | 表 | 行 | 列 |
---|---|---|---|---|
ES | 索引 | 类型 | 文档 | 字段 |
Relational DB | Databases | Tables | Rows | Columns |
---|---|---|---|---|
Elasticsearch | Indices | Types | Documents | Fields |
在ES中文档属于一种type,而这些类型存储在索引中。Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。
例如创建一个学生管理 索引(index)含有一个学生type,班级type,每个学生type相当数据库中的学生表,每一条记录是一个document,每列是一个字段。
Insert
PUT /studentmanager/student/1
{
"name":"gy",
"age" :10,
"class" :"一班",
“interesting”:["音乐",“篮球”,"看书"]
}
数据库 | 表 | 行 | 列 |
---|---|---|---|
索引 | 类型 | 文档 | 字段 |
studentmanager | student | json | name,age,class,intersting |
Query
id查询
//单条document查询
GET /studentmanager/student/1
{
"_index" : "studentmanager",
"_type" : "student",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source":{
"name" :"gy",
"age" :10,
"class" :"一班",
“interesting”:["音乐",“篮球”,"看书"]
}
}
我们通过HTTP方法GET来检索文档,同样的,我们可以使用DELETE方法删除文档,使用HEAD方法检查某文档是否存在。如果想更新已存在的文档,我们只需再PUT一次。
查询所有
//查询全部 默认返回前10条
GET /studentmanager/student/_search
{
"took": 6,
"timed_out": false,
"_shards": { ... },
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "studentmanager",
"_type": "student",
"_id": "3",
"_score": 1,
"_source": {
"name" :"gy",
"age" :10,
"class" :"一班",
“interesting”:["音乐",“篮球”,"看书"]
}
},
{
"_index": "studentmanager",
"_type": "student",
"_id": "1",
"_score": 1,
"_source": {
...
}
},
{
"_index": "studentmanager",
"_type": "student",
"_id": "2",
"_score": 1,
"_source": {
...
}
}
]
}
}
条件查询
GET /studentmanager/student/_search?q=name:gy
DSL(Domaim Specific Language)查询
使用请求体代替,这个请求体使用JSON表示,其中使用了match语句(查询类型之一)。
GET /studentmanager/student/_search
{
"query" : {
"match" : {
"name" : "gy"
}
}
}
filter查询
GET /studentmanager/student/_search
{
"query" : {
"filtered" : {
"filter" : {
"range" : {
"age" : { "gt" : 30 } <1>
}
},
"query" : {
"match" : {
"name" : "gy" <2>
}
}
}
}
}
<1> 这部分查询属于区间过滤器(range filter),它用于查找所有年龄大于30岁的数据——gt为"greater than"的缩写。
<2> 这部分查询与之前的match语句(query)一致。
相关性全文搜索
GET /studentmanager/student/_search
{
"query" : {
"match" : {
"about" : "篮球"
}
}
}
相应结果为:
{
...
"hits": {
"total": 2,
"max_score": 0.16273327,
"hits": [
{
...
"_score": 0.16273327, <1>
"_source": {
"name": "John",
"age": 25,
"about": "I love to 篮球",
"interests": [ "sports", "music" ]
}
},
{
...
"_score": 0.016878016, <2>
"_source": {
"first_name": "Jane",
"age": 32,
"about": "I like to 篮球",
"interests": [ "music" ]
}
}
]
}
}
大家看到每条结果对应一个评分。
这个例子很好的解释了Elasticsearch如何在各种文本字段中进行全文搜索,并且返回相关性最大的结果集。相关性(relevance)的概念在Elasticsearch中非常重要,而这个概念在传统关系型数据库中是不可想象的,因为传统数据库对记录的查询只有匹配或者不匹配。
高亮搜索
GET /studentmanager/student/_search
{
"query" : {
"match_phrase" : {
"about" : "篮球"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
//结果
{
...
"hits": {
"total": 1,
"max_score": 0.23013961,
"hits": [
{
...
"_score": 0.23013961,
"_source": {
"name": "John",
"age": 25,
"about": "I love to 篮球",
"interests": [ "sports", "music" ]
},
"highlight": {
"about": [
"I love to go <em>rock</em> <em>climbing</em>" <1>
]
}
}
]
}
}
聚合 分析
老铁,你这功能很强大。
例如找出所有同学的共同爱好
GET /studentmanager/student/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}
查询结果为
{
...
"hits": { ... },
"aggregations": {
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "forestry",
"doc_count": 1
},
{
"key": "sports",
"doc_count": 1
}
]
}
我们可以看到两个同学对音乐有兴趣,一个喜欢林学,一个喜欢运动。这些数据并没有被预先计算好,它们是实时的从匹配查询语句的文档中动态计算生成的。如果我们想知道所有姓名"Smith"的人最大的共同点(兴趣爱好),我们只需要增加合适的语句既可
当然还有些更为复杂 多条件查询 或者 求平均值 最大值等等
分布式的特性
将你的文档分区到不同的容器或者分片(shards)中,它们可以存在于一个或多个节点中。
将分片均匀的分配到各个节点,对索引和搜索做负载均衡。
冗余每一个分片,防止硬件故障造成的数据丢失。
将集群中任意一个节点上的请求路由到相应数据所在的节点。
无论是增加节点,还是移除节点,分片都可以做到无缝的扩展和迁移。
网友评论