来源:
多年前,一个叫做Shay Banon的刚结婚不久的失业开发者,由于妻子要去伦敦学习厨师,他便跟着也去了。在他找工作的过程中,为了给妻子构建一个食谱的搜索引擎,他开始构建一个早期版本的Lucene。
直接基于Lucene工作会比较困难,所以Shay开始抽象Lucene代码以便Java程序员可以在应用中添加搜索功能。他发布了他的第一个开源项目,叫做“Compass”。后来Shay找到一份工作,这份工作处在高性能和内存数据网格的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也是理所当然需要的。然后他决定重写Compass库使其成为一个独立的服务叫做Elasticsearch。
第一个公开版本出现在2010年2月,在那之后Elasticsearch已经成为Github上最受欢迎的项目之一,代码贡献者超过300人。一家主营Elasticsearch的公司就此成立,他们一边提供商业支持一边开发新功能,不过Elasticsearch将永远开源且对所有人可用。
特点:
elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
几乎每个系统都会有一个搜索的功能,当搜索做到一定程度时,维护和扩展起来难度就会慢慢变大,所以很多公司都会把搜索单独独立出一个模块,用ElasticSearch等来实现。
Elasticsearch还可用来做日志分析系统:ELK。是ElasticSearch + Logstash +Kibana 的简称。L:是一个完全开源的工具,他可以对你的日志进行收集、分析,并将其存储供以后使用(如,搜索)。 kibana 也是一个开源和免费的工具,他 Kibana 可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。
ElasticSearch的使用非常广泛。例如:UBER、LinkedIn、ebay等公司。
安装:
1、下载地址
https://www.elastic.co/downloads2、两种运行方式:
第一种:直接解压,找到bin目录,然后运行程序,用nohup或者elasticsearch –d,https://www.elastic.co/guide/en/elasticsearch/reference/current/setup.html
第二种:以系统服务的形式运行(推荐这种)
官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-service.html
gitHub:
https://github.com/elastic/elasticsearch-servicewrapper
3、elasticsearch-head
辅助管理集群的可视化工具,可以用来查询数据和查看管理集群。gitHub:
https://github.com/mobz/elasticsearch-head
4、插件
Elasticsearch本身不支持中文,需要下插件以支持中文分词https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-smartcn.html
如果还嫌麻烦,可以直接去gitHub上看一看“elasticsearch-rft”这个项目,直接集成了elasticSearch所需的所有中文东西。https://github.com/medcl/elasticsearch-rtf
5、http client
这里选用的是官方提供的elasticsearch-phphttps://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html
elasticsearch创建:
1、ElasticSearch中数据名称和数据库中的对应关系
index ~~ databasetype ~~ table
document ~~ row
2、创建index的结构
不创建也可以,elasticsearch本身有一些默认的配置,但是一般都是自己创建。PUT /my_index
{
"settings": { ... any settings ... },
"mappings": {
"type_one": { ... any mappings ... },
"type_two": { ... any mappings ... },
...
}
创建好的结构PHP版:
....
由于代码很长,我就不贴了
大体结构是
body:{
settings:{
number_of_shards:
number_of_replicas:
analysis { filter:{}, tokenizer:{}, analyzer:{} }
},
mappings:{
“your_type1”:{ … properties:{ id:{ type:long … } … }
…
}
}
3、索引设置
(Elasticsearch 提供了优化好的默认配置。除非你明白这些配置的行为和为什么要这么做,请不要修改这些配置。)number_of_shards : elasticsearch 主分片点的个数 (默认是5)
number_of_replicas:每个分片的副本 (默认是1)
分片:
当有大量的文档时,由于内存、硬盘等硬件资源的能力,没法及时的相应客户端的请求,一个节点就不够用。这时候,数据可以分为较小的称之为分片(shard)的部分。每个分片可以放在不同的服务器上,因此,数据可以在集群节点中传播,当你查询的索引分布在多个分片上时,Elasticsearch会把查询发送给每个相关的分片,并将结果合并在一起,应用程序对于分片来讲是透明的(不知道也无需知道分片的存在)。
副本:
为了提高查询的吞吐量,可以使用副本。副本只是一个分片的精确复制,每个分片可以有零到多个副本。换句话说:Elasticsearch可以有许多相同的分片,其中之一被自动选择去更改索引操作。这种特殊的分片称之为:主分片(primary shard),其余的称之为副本分片(replica shard)。在主分片丢失的时候,例如该分片数据所在的服务器不可用,集群将副本提升为新的主分片。
analysis 机制用于进行全文本(Full Text)的分词,以建立提供搜索用的反向索引。
analysis 机制包含了一下步骤:首先,把一整块的文本分割成单独独立的用于倒排索引的词(terms)。
然后,把这些分词整合成用于改善查询或其他操作的标准的结构。
以上工作被analyzers完美的解决了。一个analyzers是一个整合了以下三个东西的wrapper:
Character filters(字符过滤器):
首先字符串经过字符过滤器(character filter),它们的工作是在标记化前处理字符串。字符过滤器能够去除HTML标记,或者转换"&"为"and"。Tokenizer(分词器):
下一步,分词器(tokenizer)被标记化成独立的词。一个简单的分词器(tokenizer)可以根据空格或逗号将单词分开(这个在中文中不适用)。
filters(过滤器):
最后,每个词都通过所有标记过滤(token filters),它可以修改词(例如将"Quick"转为小写),去掉词(例如停用词像"a"、"and"``"the"等等),或者增加词(例如同义词像"jump"和"leap")
注意:整个流程就是 character filters => Tokenzier => Tokenzier filters
elastic提供了很多开箱即用的字符过滤器、分词器和过滤器,可以参照官网。
https://www.elastic.co/guide/en/elasticsearch/guide/current/analysis-intro.html
中文版:
http://es.xiaoleilu.com/052_Mapping_Analysis/40_Analysis.html
这种DSL的东西没有必要记,现用现查就行了
以下是ElasticSearch内置的Analyzer、tokenizer、tokenizer filter、character filter
Analyzer(分析器):
Analyzer名字 | 作用 |
---|---|
standard | standard tokenizer, standard filter, lower case filter, stop filter |
simple | lower case tokenizer |
stop | lower case tokenizer, stop filter |
keyword | 不分词,内容整体作为一个token(not_analyzed) |
whitespace | 正则表达式分词,默认匹配\W+ |
lang | 各种语言 |
snowball | standard tokenizer, standard filter, lower case filter, stop filter,snowball filter |
custom | 一个Tokenizer, 零个或多个Token Filter, 零个或多个Char Filter |
tokenizer
standard | |
edgeNGram | |
keyword | 不分词 |
letter | 按单词分 |
lowercase | letter tokenizer, lower case filter |
nGram | |
whitespace | 以空格为分隔符拆分 |
pattern | 定义分隔符的正则表达式 |
uax_url_email | 不拆分url和email |
path_hierarchy |
处理类似/path/to/somthing样式的字符串 |
tokenizer filter名字 | tokenizer filter的作用 |
standard | |
asciifolding | |
length | 去掉太长或者太短的 |
lowercase | 转成小写
|
nGram | |
edgeNGram | |
porterStem | 波特词干算法 |
shingle | 定义分隔符的正则表达式 |
stop | 移除 stop words |
word_delimiter | 将一个单词再拆成子分词 |
stemmer | |
stemmer_override | |
keyword_marker | |
keyword_repeat | |
kstem | |
snowball | |
phonetic | 插件 https://github.com/elasticsearch/elasticsearch-analysis-phonetic |
synonyms |
处理同义词 |
dictionary_decompounder,hyphenation_decompounder | 分解复合词 |
reverse | 反转字符串 |
elision | 去掉缩略语 |
truncate | 截断字符串 |
unique | |
pattern_capture | |
pattern_replace | 用正则表达式替换 |
trim |
去掉空格 |
limit | 限制token数量 |
hunspell | 拼写检查 |
common_grams | |
arabic_normalization,persian_normalization |
character filter 的名字 | character filter的作用 |
mapping | 根据配置的映射关系替换字符 |
html_strip | 去掉HTML元素 |
pattern_replace | 用正则表达式处理字符串 |
ElasticSearch的基本用法:
elasticsearch的curd操作很简单:
elasticsearch的集群搭建:
ElasticSearch创建集群非常的简单,把三个服务器中的elasticsearch.yml文件中的”cluster.name”改为相同的名字就可以。
ElasticSearch在项目中的应用
1、创建index
2、在程序中使用elasticsearch-PHP,来向ES发送rest请求。
$param = [ 'index' => ESConsts::INDEX, 'type' => [ESConsts::TYPE_DOC, ESConsts::TYPE_HOSPITAL], 'body' => [ 'size' =>9000, 'from' =>0, 'query' => [ 'filtered' => [ 'query' => [ "multi_match" => [ "query" => $keyword, "type" => "best_fields", "fields" => [ "name", "hospitals_name", "hospitals_name.hospitals_name_pinyin", "name.name_pinyin" ], "tie_breaker" => 0.3, "minimum_should_match" => "10%" ], ], 'filter' => [ 'term' => ['city' => $city] ], ] ], 'highlight' =>[ 'fields' => [ 'hospitals_name' => [ "pre_tags" => ["<font color='#00FFFF'>"], "post_tags" => ["</font>"] ], 'name' => [ "pre_tags" => ["<font color='#00FFFF'>"], "post_tags" => ["</font>"] ], 'hospitals_name.hospitals_name_pinyin' => [ "pre_tags" => ["<font >"], "post_tags" => ["</font>"] ], 'name.name_pinyin' => [ "pre_tags" => ["<font >"], "post_tags" => ["</font>"] ] ] ] ] ]; $response = $client->search($param);