1.1Lucene倒排索引:
搜索引擎的关键就是建立倒排索引结构。
假设有两篇文章1和文章2
文章1内容:Tom lives in Guangzhou, I live in Guangzhou,too
文章2内容:He once live in Shanghai
1.对内容进行处理,取得关键词
文章1所有关键词: [tom][live][guangzhou][i][live][guangzhou]
文章2所有关键词:[he][live][Shanghai]
2.建立倒排索引
之前的对应关系是:“文章号”对应“文章中所有关键词”
倒排索引把这个关系倒过来 :“关键词”对应“拥有该关键词的所有文章号”
仅知道关键词在文章中出现还不够,我们还需要知道关键词在文章中的出现次数和位置(字符位置(是文章中的第几个字符) or 关键词位置(是文章中的第几个关键词))
这样就像一个字典
1.2基础知识
文本(一段普通的非结构化文字),经过分析(依赖分词器,将文本转化成索引词),转化成索引词(一个能够被索引到的精确值,foo、Foo、FOO几个是不同的索引词)
集群cluster有一个或多个节点组成,对外提供索引和搜索功能。一个集群的默认名字为“Elasticsearch”,一个节点只能加入一个集群,当节点被设置成相同集群名称时,就会自动加入该集群。你可以建立多个独立集群,但每个集群都有不同的名称。
节点node
一个节点是一个逻辑上独立的服务,可以存储数据,参与集群的索引和搜索功能。节点会在启动时默认被分配一个节点名,也可以自己为它定义。你可以为一个节点配置加入某个特定集群,默认情况下会加入名为Elasticsearch的集群中。
路由routing
存储一个文档时,他会存储在唯一的主分片中,具体在哪个分片根据文档的ID生成。
分片shard
索引index是指向主分片和副分片的逻辑空间。我们使用时只需要指定分片数量。
为什么需要分片?答:一个索引可以存储很大的数据,可以超过一个节点的物理存储限制,一台物理机器代表的以恶搞节点不一定能存储这么多数据,为了解决这个问题,Elasticsearch将索引分解成多个分片,当你创建一个索引时定义你需要的分片数量。每个分片是一个全功能的独立单元,可以托管在集群的任何节点。
主分片primary shard
当你存储一个文档时,它会首先存储在主分片中,然后复制倒不同的副本中,默认一个索引有5个主分片。你可以事先定制分片数量,分片一旦建立,数量不能更改。
副本分片 replica shard
每一个分片有0个或多个副本,当主分片失败时,可以从副本分片中选择一个作为主分片,查询时也可以到主分片或者副本分片中查询(副本分片和主分片必须部署在不同节点上)
默认情况下,每个索引有5个主分片,每个主分片有一个副本,故集群中至少有两个节点,你将拥有5个主分片,5个副本分片。
注意:一个索引的文档存储数量为2147283519。
索引index
索引时具有相同结构的文档集合。比如一个客户信息索引,一个产品目录索引,i 个订单数据索引。一个集群中可以定义多个索引。
类型type
在一个索引中,可以定义一个或多个类型,类型是索引的逻辑分区,通常一种类型并定义为具有一组公共字段的文档,即一个type下面的document都有相同的field。
文档document
文档是存储在ES中的一个JSON格式字符串,呢个文档都是一个JSON(键值对)对象。
字段field
一个文档中包含0个或多个字段。
主键ID
ID是一个文档的唯一标识,如果存库时没有提供ID,系统会自动生成,文档的index/type/id 是唯一的
注意:在ES6.0中删除了每个索引index具有多个映射类型type的功能。一个index中只能有一个type。 这是计划中完全删除地图类型的第一步。 在5.x中创建的索引将继续支持多种映射类型。
1.3JSON
JSON的两种结构
1.名称/值对的集合,用花括号将这些值进行关联
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
}
2.值的有序集合,即数组,使用[ ]将多个带花括号记录组合成一个值
{
"people":[
{firstName:"BB","lastName":"CC","email":"ssss"},
{firstName:"AA","lastName":"JJ","email":"asad"},
{firstName:"DD","lastName":"OO","email":"PNBH"}
]
}
1.4启动elasticsearch
进入elasticsearch文件目录,
$ bin/elasticsearch
浏览器访问http://localhost:9200/ ,启动成功
如果要停止,控制台按下Ctrl+C
1.5RESTful API with JSON over HTTP
所有其他语言可以使用RESTful API 通过端口9200和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用curl
命令来和 Elasticsearch 交互。
一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:
POST方法新建一个资源,GET方法取得一个资源,PUT方法更新一个资源(如果ID不存在就新增一个资源),DELETE方法删除一个资源,如果只想检查一下文档是否存在,你可以试用HEAD来替代GET方法,这样就是会返回HTTP头文件curl -i -XHEAD
当用POST新增资源时,PATH API路径应该为index/type/id
计算集群中文档的数量
curl -XGET 'http://localhost:9200/_count?pretty'
返回结果:
{
"count" : 0,
"_shards" : {
"total" : 0,
"successful" : 0,
"skipped" : 0,
"failed" : 0
}
}
也可以使用curl -i -XGET 'http://localhost:9200/_count?pretty'
返回HTTP消息####1.6基本操作
插入数据(创建一个新文档)
index/type/id 三者唯一确定一个文档,想要保证文档是新加入的,最简单的方式是让ES自动生成唯一id
curl -XPOST 'http://localhost:9200/business/indiana/1?pretty' -H 'Content-Type: application/json' -d'
{
"Business Name": "PORTLAND SERVICE CO INC ",
"Business ID": "194035-060 ",
"Entity Type": "Domestic For-Profit Corporation ",
"Business Status": "Active ",
"Creation Date": "05/28/1925 "
}'
返回结果:
{
"_index" : "business",
"_type" : "indiana",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2, #主分片,副分片
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
修改文档
curl -XPUT 'http://localhost:9200/business/indiana/1?pretty' -H 'Content-Type: application/json' -d'
{
"Business Name": "new-PORTLAND SERVICE CO INC ",
"Business ID": "194035-061 ",
"Entity Type": "Domestic For-Profit Corporation ",
"Business Status": "notActive ",
"Creation Date": "05/28/1925 "
}'
返回结果:
{
"_index" : "business",
"_type" : "indiana",
"_id" : "1",
"_version" : 2, #发现更新后version增加了
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
查询文档
curl -XGET 'http://localhost:9200/business/indiana/1?pretty' -H 'Content-Type: application/json'
返回结果:
{
"_index" : "business",
"_type" : "indiana",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"Business Name" : "new-PORTLAND SERVICE CO INC ",
"Business ID" : "194035-061 ",
"Entity Type" : "Domestic For-Profit Corporation ",
"Business Status" : "notActive ",
"Creation Date" : "05/28/1925 "
}
}
删除文档
curl -XDELETE 'http://localhost:9200/business/indiana/1'
删除索引
curl -XDELETE 'http://localhost:9200/business'
1.6批量操作数据的bulk方法
bulk方法支持的操作有 index, create, delete , update
我们可以把需要操作的数据写在一个example.json文件中,
es会以\n结尾来判断一条json数据,故一条json数据需要写在一行中,数据前一行是对该条数据的操作,可以指定_index,_type,_id,像图中这样{"index":{}} 是因为在curl语句中指定了_index和_type,不指定_id时,_id由es随机分配。
进入example.json所在文件夹,运行
$ curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/bank/account/_bulk --data-binary "@mobile.json"; echo
如果有多个.json文件需要引入,可以将多个.json文件放入一个文件夹中,遍历文件夹中的文件。具体方法如下:
创建文件test.sh
#!/usr/bin/env bash
for file in ./文件夹名/*
do
echo $file
curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/bank3/account3/_bulk --data-binary "@$file";
done
终端运行
chmod u+x test.sh
./test.sh