一.启动elasticsearch
/**
1.在elasticsearch安装目录的bin目录上,按shif+t右键,在此处打开命令行窗口,
2.输入:elasticsearch.bat,回车
3.服务器中输入:localhost:9200 ,查看结果
*/
{
  "name" : "YG6iddi",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "fw8DvwVSR3i6mcPqDFfmpw",
  "version" : {
    "number" : "6.5.3",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "159a78a",
    "build_date" : "2018-12-06T20:11:28.826501Z",
    "build_snapshot" : false,
    "lucene_version" : "7.5.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}
//启动成功

二.启动Kibana-sense工具
/**
1.在elasticsearch安装目录的bin目录中,双击kibana.bat,kibana
2.在服务器中输入:localhost:5601 查看结果
3.点击菜单:Dev Tools 菜单
4.在console 写操作命令即可,自动保存,页面刷新也不回丢失:
*/

三、索引特定类型信息
/**
0.新建索引类型
1.每个家庭成员索引一个文档,包含该成员的所有信息。
2.每个文档都将是 family 类型 。
3.该类型位于 索引 kibana_1 内。
4.该索引保存在我们的 Elasticsearch 集群中。
5.索引的文档是不可变的:他们不能被修改,只能被替换,重新索引
*/
//操作如下
PUT /kibana_1/family/1
{
    "first_name" : "张",
    "last_name" :  "一",
    "age" :        29,
    "about" :      "I love she",
    "interests": [ "food", "sleep" ]
}
//kibana_1:索引名称
//family:类型名称
//1:特定成员ID
 
//如果希望id自动生成,把PUT改成POST即可,此时id为20个字符的GUID字符串
POST /kibana_1/family
	"first_name" : "张",
    "last_name" :  "一",
    "age" :        29,
    "about" :      "I love she",
    "interests": [ "food", "sleep" ]
}
 四、检索索引值
 
//1.所有索引检索
GET _search
{
  "query": {
    "match_all": {}
  }
}
//2特定索引,特定family类型检索
GET kibana_1/family/_search
{
  "query":{
    "match_all": {}
  }
  
}
//3.根据id检索
GET kibana_1/family/1
//返回结果包含元数据,以及_source属性,内容是family成员原始JSON文档
{
  "_index" : "kibana_1",
  "_type" : "family",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "first_name" : "张",
    "last_name" : "一",
    "age" : 29,
    "about" : "I love she",
    "interests" : [
      "food",
      "sleep"
    ]
  }
}
//4.id拓展检索
GET kibana_1/family/1/_source //(仅_source)
GET /kibana_1/family/1?_source //(信息全)
GET /kibana_1/family/1?_source=first_name,about //(查询_source指定字段)
//5.指定参数检索
/**
查询年龄为29岁的成员信息,采用高亮搜索,很容易查找,
一般涉及一个查询字符串(_query-string_),通过url来传递参数,
注意,参数不支持中文匹配
*/
GET /kibana_1/family/_search?q=age: 29
//6.查询表达式检索(外层括号{}要单独成行)
GET kibana_1/family/_search
{
	"query" :{
		"match":{
			"age":29
		}
	}
	
}
//7.复杂检索,
/**
使用过滤器,高效执行结构化查询,过滤出年龄大于30且小于52,且about为"I love she"的成员
match部分和之前一样,range部门是一个过滤器
*/
GET kibana_1/family/_search
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "about" : "I love she" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30,"lt":52 } 
                }
            }
        }
    }
}
//8.全文搜索
/**
如果搜索无固定条件,而是根据个别单词取匹配,比如about中为him的成员
传统数据库很难搞定,但是es就很轻松,Elasticsearch 默认按照相关性得分排序,匹配度越高,位置越靠前
*/
GET kibana_1/family/_search
{
  "query": {
    "match": {
      "about": "him"
    }
  }
}
//9.短语匹配
/**
有时候想要精确匹配一系列单词或者短语 。 
比如, 我们想执行这样一个查询,仅匹配同时包含 “rock” 和 “climbing” ,并且 二者以短语 love she 的形式紧挨着的家庭成员记录。
*/
GET kibana_1/family/_search
{
  "query": {
    "match_phrase": {
      "about": "love she"
    }
  }
}
//10.高量查询
/**
许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。
在 Elasticsearch 中检索出高亮片段也很容易。
返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分,这个部分包含了 about 属性匹配的文本片段,并以 HTML 标签 <em></em> 封装:
*/
GET kibana_1/family/_search
{
  "query": {
    "match_phrase": {
      "about": "love she"
    }
  },
  "highlight": {
    "fields": {
      "about": {}
    }
  }
}
/**
多出的部门,和_source并列
"highlight" : 
{
  "about" : [
	"I <em>love</em> <em>she</em>"
  ]
}
*/
//11.分析聚合功能

五、集群健康状况
/**
Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是 集群健康 , 它在 status 字段中展示为 green 、 yellow 或者 red 。
status 字段是我们最关心的,指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
1.green-所有的主分片和副本分片都正常运行。
2.yellow-所有的主分片都正常运行,但不是所有的副本分片都正常运行。
3.red-有主分片没能正常运行。
后续会讲解什么是主分片、副分片相关信息
*/
//集群健康状态查看
GET /_cluster/health
//结果如下:
{
  "cluster_name" : "elasticsearch",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 6,
  "active_shards" : 6,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 5,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 54.54545454545454
}
六、索引介绍
/**
索引:保存相关数据的地方。我们往Elasticsearch添加数据的时候,需要用到索引。索引实际上是指向一个或多个物理分片的逻辑命名空间。
分片:一个分片是一个底层的工作单元,它保存了全部数据的一部分,一个分片是一个Lucene实例,它本身就是一个很完整的搜索引擎,我们的文档
	    被存储和索引到分片内,但是应用程序是直接和索引打交道的,而不是直接与分片进行交互。
		一个分片可以是主分片或者副分片,索引内任意一个文档都归属于一个主分片,所以主分片的个数决定者索引能够存储的最大数据量
		notes:技术上而言,一个主分片最大可存储integer.MAX_VALUE-128个文档,但实际最大值还要参考你的使用场景,比如硬件、文档的大小和复杂程度等
副分片:主分片的拷贝。副分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。
分片数:主分片的个数,在索引建立时就已经确定了,但副分片的个数可以随时修改。
*/
//1.创建一个索引
/**
分配三个主分片和一个副分片(每个主分片有一个副分片)
默认的话,会被分配5个主分片shards
*/
PUT /es_index_1
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}
//结果如下:
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "es_index_1"
}
//查询下索引es_index_1
GET /es_index_1/_search
//结果如下:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}
//2.列表展示所有索引
GET _cat/indices
//3.删除指定索引
DELETE 索引名(多个索引用逗号隔开)
//4.判断一个索引是否存在
/**存在:200 - OK,不存在:404 - Not Found,存在与否,只是判断当前检查时的状态,当前不存在,下一秒也可能存在*/
HEAD /kibana_1/family/1
//5.删除指定id的索引值
/**存在:200 - OK,不存在:404 - Not Found*/
DELETE /kibana_1/family/1

七、处理冲突
同时索引一个文档内容时,出现冲突情况,造成一方数据错误
//1. 悲观并发控制
/**
这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,
确保只有放置锁的线程能够对这行数据进行修改。
*/
//2.乐观并发控制
/**
Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。
应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据、或者将相关情况报告给用户。
*/
//3.乐观并发控制方式
/**
每个文档都有一个 _version (版本)号,当文档被修改时版本号递增。 Elasticsearch 使用这个 _version 号来确保变更以正确顺序得到执行
注意,此时要求:version参数必须等于(==)当前实际_version,才能修改成功
*/
//此时version为1,设置成功
PUT /es_index_1/blog/version=2
{
  "title": "My first blog entry",
  "text":  "Starting to get the hang of this..."
}
//此时会出错,409-冲突,version参数必须等于(==)当前实际version,才能修改成功
PUT /es_index_1/blog/1?version=1
{
  "title": "My first blog entry",
  "text":  "Starting to get the hang of this..."
}
//4.通过外部系统使用版本控制
/**注意,此时要求:version参数必须大于(>)当前实际version,才能修改成功,否则报错*/
//此时设置外部version=5成功
PUT /es_index_1/blog/2?version=5&version_type=external
{
  "title": "My first external blog entry",
  "text":  "This is a piece of cake..."
}
//此时会出错,409-冲突,version参数必须大于(>)当前实际version,才能修改成功
PUT /es_index_1/blog/2?version=5&version_type=external
{
  "title": "My first external blog entry",
  "text": 
  "This is a piece of cake..."
}
//
POST /es_index_1/blog/1/_update
{
   "doc" : {
      "tags" : [ "testing" ],
      "views": 0
   }
}