基本概念

索引

  • 索引(index)是Elasticsearch对逻辑数据的逻辑存储,所以它可以分为更小的部分。
  • 可以把索引看成关系型数据库的表,索引的结构是为快速有效的全文索引准备的,特别是它不存储原始值。
  • 可以把Elasticsearch的索引看成MongoDB里的一个集合。
  • Elasticsearch可以把索引存放在一台机器或者分散在多台服务器上,每个索引有一或多个分片(shard),每个分片可以有多个副本(replica)。

文档

  • 存储在Elasticsearch中的主要实体叫文档(document)。用关系型数据库来类比的话,一个文档相当于数据库表中的一行记录。
  • Elasticsearch和MongoDB中的文档类似,都可以有不同的结构,但Elasticsearch的文档中,相同字段必须有相同类型。
  • 文档由多个字段组成,每个字段可能多次出现在一个文档里,这样的字段叫多值字段(multivalued)。
  • 每个字段的类型,可以是文本、数值、日期等。字段类型也可以是复杂类型,一个字段包含其他子文档或者数组。

映射

  • 所有文档写进索引之前都会先进行分析,如何将输入的文本分割为词条、哪些词条又会被过滤,这种行为叫做映射(mapping)。一般由用户自己定义规则

文档类型

  • 在Elasticsearch中,一个索引对象可以存储很多不同用途的对象。例如,一个博客应用程序可以保存文章和评论。
  • 每个文档可以有不同的结构。
  • 不同的文档类型不能为相同的属性设置不同的类型。例如,在同一索引中的所有文档类型中,一个叫title的字段必须具有相同的类型。

RESTful API

在Elasticsearch中,提供了功能丰富的RESTful API的操作,包括基本的CRUD、创建索引、删除索引等操作。

1. 创建非结构化索引

在Lucene中,创建索引是需要定义字段名称以及字段的类型的,在Elasticsearch中提供了非结构化的索引,就是
不需要创建索引结构,即可写入数据到索引中,实际上在Elasticsearch底层会进行结构化操作,此操作对用户是透
明的。

创建空索引:

PUT http://172.16.55.185:9200/pippen

{
  "settings": {
      "index": {
           "number_of_shards": "2", #分片数
           "number_of_replicas": "0" #副本数
      }
   }
}
#删除索引
DELETE http://172.16.55.185:9200/pippen

{
	"acknowledged": true
}

2. 插入数据

URL 规则
POST http://172.16.55.185:9200/{索引}/{类型}/
不指定ID时 es 将会随机产生一个ID

POST http://172.16.55.185:9200/pippen/user/1001

# 请求
{
    "id": 1001,
    "name": "张三",
    "age": 20,
    "sex": "男"
}

# 响应
{
    "_index": "pippen",
    "_type": "_doc",
    "_id": "e2zkN3ABU2jSZT_ME8Ts",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

说明:非结构化的索引,不需要事先创建,直接插入数据默认创建索引。

3. 更新数据

在Elasticsearch中,文档数据是不为修改的,但是可以通过覆盖的方式进行更新

PUT http://172.16.55.185:9200/pippen/user/1001

{
	"id":1001,
	"name":"张三",
	"age":21,
	"sex":"女"
}

# 局部更新
# 注意:这里多了_update标识
POST http://172.16.55.185:9200/pippen/user/1001/_update
{
	"doc":{
		"age":23
	}
}

4. 删除数据

在Elasticsearch中,删除文档数据,只需要发起DELETE请求即可

DELETE http://172.16.55.185:9200/pippen/user/1001

注意
result表示已经删除,version也更加了。
如果删除一条不存在的数据,会响应404

说明:
删除一个文档也不会立即从磁盘上移除,它只是被标记成已删除。
Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理

5. 搜索数据

5.1 根据ID进行搜索

GET http://172.16.55.185:9200/pippen/user/e2zkN3ABU2jSZT_ME8Ts

#返回结果
{
    "_index": "pippen",
    "_type": "_doc",
    "_id": "e2zkN3ABU2jSZT_ME8Ts",
    "_version": 1,
    "found": true,
    "_source": {  ## 原始数据
        "id": 1001,
        "name": "张三",
        "age": 20,
        "sex": "男"
    }
}

5.2 搜索全部数据

响应:(默认返回10条数据)

GET http://172.16.55.185:9200/pippen/user/_search
{
    "took": 41,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 1.0,
        "hits": [
            {
                "_index": "pippen",
                "_type": "_doc",
                "_id": "e2zkN3ABU2jSZT_ME8Ts",
                "_score": 1.0,
                "_source": {
                    "id": 1001,
                    "name": "张三",
                    "age": 20,
                    "sex": "男"
                }
            }
        ]
    }
}

6. 高亮显示

POST http://172.16.55.185:9200/pippen/user/_search

{
	"query": {
		"match": {
			"name": "张三 李四"
		}
	},
	"highlight": {
		"fields": {
			"name": {}
		}
	}
}

7. 结构化查询

7.1 term查询

term 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型):

http://172.16.55.185:9200/pippen/_doc/_search

# 请求
{
    "query" : {
        "term" : {
            "age" : 20
        }
    }
}

# 响应
{
    "took": 20,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 1.0,
        "hits": [
            {
                "_index": "pippen",
                "_type": "_doc",
                "_id": "e2zkN3ABU2jSZT_ME8Ts",
                "_score": 1.0,
                "_source": {
                    "id": 1001,
                    "name": "张三",
                    "age": 20,
                    "sex": "男"
                }
            }
        ]
    }
}

7.2 terms查询

termsterm 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配:

http://172.16.55.185:9200/pippen/_doc/_search

# 请求
{
    "query" : {
        "terms" : {
            "age" : [20,21]
        }
    }
}

7.3 range查询

range 过滤允许我们按照指定范围查找一批数据
范围操作符包含:
gt :: 大于
gte :: 大于等于
lt :: 小于
lte :: 小于等于

http://172.16.55.185:9200/pippen/_doc/_search

# 请求
{
    "query" : {
        "range" : {
            "age" : {
		"gte": 20,
		"lte": 22
	    }
        }
    }
}

7.4 exists 查询

exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的 IS_NULL 条件

http://172.16.55.185:9200/pippen/_doc/_search

# 请求
{
    "query" : {
        "exists" : { # 必须包含
            "field" :"age"
	    
        }
    }
}

7.5 match查询

match 查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析 match 一下查询字符

{
    "match": {
        "tweet": "About Search"
    }
}

如果用 match 下指定了一个确切值,在遇到数字,日期,布尔值或者 not_analyzed 的字符串时,它将为你搜索你给定的值:

{ "match": { "age": 26 }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}

7.6 bool查询

bool 查询可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符:
must :: 多个查询条件的完全匹配,相当于 and
must_not :: 多个查询条件的相反匹配,相当于 not
should :: 至少有一个查询条件匹配, 相当于 or
这些参数可以分别继承一个查询条件或者一个查询条件的数组:

{
    "bool": {
        "must": { "term": { "folder": "inbox" }},
        "must_not": { "term": { "tag": "spam" }},
        "should": [
            { "term": { "starred": true }},
            { "term": { "unread": true }}
        ]
    }
}

8. 过滤查询

POST http://172.16.55.185:9200/pippen/_doc/_search
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "age": 20
                 }
             }
        }
    }
}

查询和过滤的对比

  • 一条过滤语句会询问每个文档的字段值是否包含着特定值。

  • 查询语句会询问每个文档的字段值与特定值的匹配程度如何。

    • 一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索。
  • 一个简单的文档列表,快速匹配运算并存入内存是十分方便的, 每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的。

  • 查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存

建议:
做精确匹配搜索时,最好用过滤语句,因为过滤语句可以缓存数据。

打赏
支付宝 微信
上一篇 下一篇