您的位置:首页 > 数据库

Elasticsearch(一)-入门以及简单的搜索语法

2017-02-26 17:48 477 查看

入门

后台运行es

如果想在后台以守护进程模式运行,添加-d参数。

/bin/elasticsearch -d -p pid

kill ${pid}


测试是否成功

curl 'http://localhost:9200/?pretty'


对比图来类比传统关系型数据库

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields


创建

创建index

PUT /megacorp


创建Types 和 document

PUT
/megacorp/employee/1
{
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}


搜索

检索文档

GET /megacorp/employee/1


result:

{
"_index" :   "megacorp",
"_type" :    "employee",
"_id" :      "1",
"_version" : 1,
"found" :    true,
"_source" :  {
"first_name" :  "John",
"last_name" :   "Smith",
"age" :         25,
"about" :       "I love to go rock climbing",
"interests":  [ "sports", "music" ]
}
}


简单搜索

搜索全部员工的请求:

GET /megacorp/employee/_search


搜索姓氏中包含“Smith”的员工:

GET /megacorp/employee/_search?q=last_name:Smith


使用DSL语句查询

查询字符串搜索便于通过命令行完成特定(ad hoc)的搜索,但是它也有局限性(参阅简单搜索章节)。Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。

DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。我们可以这样表示之前关于“Smith”的查询:

POST /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}


更复杂的搜索

我们让搜索稍微再变的复杂一些。我们依旧想要找到姓氏为“Smith”的员工,但是我们只想得到年龄大于30岁的员工。我们的语句将添加过滤器(filter),它使得我们高效率的执行一个结构化搜索:

POST /megacorp/employee/_search
{
"query": {
"filtered": {
"filter": {
"range": {
"age": {
"lt": 30
}
}
},
"query": {
"match": {
"last_name": "smith"
}
}
}
}
}


全文搜索

搜索所有喜欢“rock climbing”的员工:

POST /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}


默认情况下,Elasticsearch根据结果相关性评分来对结果集进行排序,所谓的「结果相关性评分」就是文档与查询条件的匹配程度。很显然,排名第一的John Smith的about字段明确的写到“rock climbing”。

但是为什么Jane Smith也会出现在结果里呢?原因是“rock”在她的abuot字段中被提及了。因为只有“rock”被提及而“climbing”没有,所以她的_score要低于John。3

这个例子很好的解释了Elasticsearch如何在各种文本字段中进行全文搜索,并且返回相关性最大的结果集。相关性(relevance)的概念在Elasticsearch中非常重要,而这个概念在传统关系型数据库中是不可想象的,因为传统数据库对记录的查询只有匹配或者不匹配。

短语搜索

目前我们可以在字段中搜索单独的一个词,这挺好的,但是有时候你想要确切的匹配若干个单词或者短语(phrases)。例如我们想要查询同时包含”rock”和”climbing”(并且是相邻的)的员工记录。

要做到这个,我们只要将match查询变更为match_phrase查询即可:

POST /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}


高亮我们的搜索

每个搜索结果中高亮(highlight)匹配到的关键字.

POST /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}


聚合

分析

Elasticsearch有一个功能叫做聚合(aggregations),它允许你在数据上生成复杂的分析统计。它很像SQL中的GROUP BY但是功能更强大。

POST /megacorp/employee/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}


如果我们想知道所有姓”Smith”的人最大的共同点(兴趣爱好),我们只需要增加合适的语句既可:

POST /megacorp/employee/_search
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}


聚合也允许分级汇总

让我们统计每种兴趣下职员的平均年龄:

GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}


分布式集群

空集群

一个节点(node)就是一个Elasticsearch实例,而一个集群(cluster)由一个或多个节点组成,它们具有相同的cluster.name,它们协同工作,分享数据和负载。当加入新的节点或者删除一个节点时,集群就会感知到并平衡数据。

集群中一个节点会被选举为主节点(master),它将临时管理集群级别的一些变更,例如新建或删除索引、增加或移除节点等。主节点不参与文档级别的变更或搜索,这意味着在流量增长的时候,该主节点不会成为集群的瓶颈。任何节点都可以成为主节点。我们例子中的集群只有一个节点,所以它会充当主节点的角色。

做为用户,我们能够与集群中的任何节点通信,包括主节点。每一个节点都知道文档存在于哪个节点上,它们可以转发请求到相应的节点上。我们访问的节点负责收集各节点返回的数据,最后一起返回给客户端。这一切都由Elasticsearch处理。

集群健康

在Elasticsearch集群中可以监控统计很多信息,但是只有一个是最重要的:集群健康(cluster health)。集群健康有三种状态:green、yellow或red。

GET /_cluster/health


添加索引

分片是Elasticsearch在集群中分发数据的关键。把分片想象成数据的容器。文档存储在分片中,然后分片分配到你集群中的节点上。当你的集群扩容或缩小,Elasticsearch将会自动在你的节点间迁移分片,以使集群保持平衡。

分片可以是主分片(primary shard)或者是复制分片(replica shard)。你索引中的每个文档属于一个单独的主分片,所以主分片的数量决定了索引最多能存储多少数据。

复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或者从别的shard取回文档。

当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整。

让我们在集群中唯一一个空节点上创建一个叫做blogs的索引。默认情况下,一个索引被分配5个主分片,但是为了演示的目的,我们只分配3个主分片和一个复制分片(每个主分片都有一个复制分片):

PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}


故障转移

在单一节点上运行意味着有单点故障的风险——没有数据备份。幸运的是,要防止单点故障,我们唯一需要做的就是启动另一个节点。

当第二个节点加入集群,三个复制分片(replica shards)也已经被分配了——分别对应三个主分片,这意味着在丢失任意一个节点的情况下依旧可以保证数据的完整性。

横向扩展

随着应用需求的增长,我们该如何扩展?加入新的节点,我们的集群会重新组织自己。

更多扩展

主分片的数量在创建索引时已经确定。实际上,这个数量定义了能存储到索引里数据的最大数量(实际的数量取决于你的数据、硬件和应用场景)。然而,主分片或者复制分片都可以处理读请求——搜索或文档检索,所以数据的冗余越多,我们能处理的搜索吞吐量就越大。

复制分片的数量可以在运行中的集群中动态地变更,这允许我们可以根据需求扩大或者缩小规模。让我们把复制分片的数量从原来的1增加到2:

PUT /blogs/_settings
{
"number_of_replicas" : 2
}


应对故障

如果一个主节点出现故障。一个集群必须要有一个主节点才能使其功能正常,所以集群做的第一件事就是各节点选举了一个新的主节点。

参考资料:

Elasticsearch权威指南

备注:

转载请注明出处:http://blog.csdn.net/wsyw126/article/details/57420333

作者:WSYW126
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息