ElasticSearch 是一個基於Lucene構建的開源、分佈式,RESTful搜索引擎。它的服務是爲具備數據庫和Web前端的應用程序提供附加的組件(便可搜索的存儲庫)。ElasticSearch爲應用程序提供搜索算法和相關的基礎架構,用戶只須要將應用程序中的數據上載到ElasticSearch數據存儲中,就能夠經過RESTful URL與其交互。ElasticSearch的架構明顯不一樣於它以前的其餘搜索引擎架構,由於它是經過水平伸縮的方式來構建的。不一樣於Solr,它在設計之初的目標就是構建分佈式平臺,這使得它可以和雲技術以及大數據技術的崛起完美吻合。ElasticSearch構建在更穩定的開源搜索引擎Lucene之上,它的工做方式與無模式的JSON文檔數據很是相似。前端
ElasticSearch的關鍵特徵java
在全部的ElasticSearch的介紹中都不可避免的提到了它是一種具備RESTful特色的搜索引擎。那麼什麼是RESTful呢?REST(Representational State Transfer表述性狀態轉移)是一種針對網絡應用的設計和開發方式,能夠下降開發的複雜性並提升系統的可伸縮性。REST有一些設計概念和準則,凡是遵循這些準則所開發的應用即具有RESTful風格。在REST風格結構中,全部的請求都必須在一個由URL制定的具體地址的對象上進行。例如,若是用/schools/表明一系列學校的話,/schools/1就表明id爲1的那所學校,依次類推。這種設計風格爲用戶提供了一種簡單便捷的操做方式,用戶能夠經過curl等RESTful API與ElasticSearch進行交互,避免了管理XML配置文件的麻煩。下面將簡單介紹linux
一下經過curl工具對ElasticSearch進行CRUD(增刪改查)操做。git
l 索引構建github
爲了對一個JSON對象進行索引建立,須要向REST API提交PUT請求,在請求中指定由索引名稱,type名稱和ID組成的URL。即redis
http://localhost:9200/<index>/<type>/[<id>]算法
例如:curl -XPUT "http://localhost:9200/movies/movie/1" -d'mongodb
{數據庫
"title": "The Godfather",網絡
"director": "Francis Ford Coppola",
"year":1972
}'
l 經過ID得到索引數據
向已經構建的索引起送GET請求,即http://localhost:9200/<index>/<type>/<id>
例如:curl -XGET "http://localhost:9200/movies/movie/1" -d''
後面不帶參數時 -d''不要也能夠
l 刪除文檔
經過ID指定的索引刪除單個文檔。URL和索引建立、獲取時相同。
例如:curl -XDELETE "http://localhost:9200/movies/movie/1" -d''
因爲ElasticSearch是專門爲分佈式環境設計的,因此怎麼去對全部節點的索引信息進行持久化是個問題。固然,除了索引信息之外,還有集羣信息,mapping和事務日誌等都須要進行持久化。當你的節點出現故障或者集羣重啓的時候,這些信息就變得很是重要。ElasticSearch中有一個專門的gateway模塊負責元信息的持久化存儲。(Solr裏邊是否是經過Zookeeper在管理這部分?)
分面是指事物的多維度屬性。例如一本書包含主題、做者、年代等方面。而分面搜索是指經過事物的這些屬性不斷篩選、過濾搜索結果的方法。固然這點在Lucene中已經獲得了實現,因此Solr也支持faceted searching。至於precolating特性則是ElasticSearch設計中的一大亮點。Precolator(過濾器)容許你在ElasticSearch中執行與上文檔、創建索引、執行查詢這樣的常規操做偏偏相反的過程。經過Precolate API,能夠在索引上註冊許多查詢,而後向指定的文檔發送prelocate請求,返回匹配該文檔的註冊查詢。舉個簡單的例子,假設咱們想獲取全部包含了」elasticsearch」這個詞的tweet,則能夠在索引上註冊一個query語句,在每一條tweet上過濾用戶註冊的查詢,能夠得到匹配每條tweet的那些查詢。下面是一個簡單的示例:
首先,創建一個索引:
curl –XPUT localhost:9200/test
接着,註冊一個對test索引的precolator 查詢,制定的名稱爲kuku
---該處在本機測試不成功,還沒找到緣由---
curl –XPUT localhost:9200/_precolator/test/kuku –d’{
「query」:{
「term」:{
「field1」:」value1」
}
}
}’
如今,能夠過濾一個文本看看哪些查詢跟它是匹配的
crul –XGETlocalhost:9200/test/type/_precolate –d’{
「doc」:{
「filed1」:」value1」
}
}’
獲得的返回結構以下
{「ok」: true, 「matches」: [「kuku」]}
--end--
ElasticSearch不一樣於Solr,從設計之初就是面向分佈式的應用環境,所以具有不少便於搭建分佈式應用的特色。例如索引能夠被劃分爲多個分片,每一個分片能夠有多個副本,每個節點能夠持有一個或多個分片,自動實現負載均衡和分片副本的路由。另外,ElasticSearch具備self-contained的特色,沒必要使用Tomcat等servlet容器。ElasticSearch的集羣是自發現、自管理的(經過內置的Zen discovery模塊實現),配置十分簡單,只要在config/elasticsearch.yml中配置相同的cluster.name便可。
ElasticSearch有一個叫作river的插件式模塊,能夠將外部數據源中的數據導入elasticsearch並在上面創建索引。River在集羣上是單例模式的,它被自動分配到一個節點上,當這個節點掛掉後,river會被自動分配到另外的一個節點上。目前支持的數據源包括:Wikipedia, MongoDB, CouchDB, RabbitMQ, RSS, Sofa, JDBC, FileSystem,Dropbox等。River有一些指定的規範,依照這些規範能夠開發適合於本身的應用數據的插件。
ElasticSearch經過river創建與各個數據源之間的鏈接。例如mongodb,這種鏈接方式多半是以第三方插件的方式,由一些開源貢獻者貢獻出來的插件創建與各類類型的數據管理系統以及MQ等創建river,索引數據的。本文主要研究的是MONGODB與ES的結合,用的是richardwilly98開發的river。
https://github.com/richardwilly98/elasticsearch-river-mongodb
1. 首先下載而且解壓Elasticsearch
- unzip elasticsearch-0.90.5.zip
2 下載而且解壓elasticsearch-servicewrapper-master.zip
- unzip elasticsearch-servicewrapper-master.zip
3 啓動elasticsearch
- cd elasticsearch-servicewrapper-master
- mv service /root/gy/elasticsearch-0.90.5/bin
4 下載river插件
- sh elasticsearch start
這裏值得一提的是river的版本必須與mongodb 和ElasticSearch匹配,若是不匹配,那麼river的時候不能將mongodb裏面全部的數據index進入es。
- ./plugin --install com.github.richardwilly98.elasticsearch/elasticsearch-river-mongodb/1.7.1
匹配規則請見下方:本次測試用的是 es 1.1.2 + mongodb 2.4.6
5 創建river
- curl -XPUT "http://localhost:9200/_river/mongodb/_meta" -d'
- {
- "type":"mongodb",
- "mongodb":{
- "servers":[{"host":「192.168.225.131","port":37017}],
- "db":"dbname",
- "collection":"collectionname",
- "gridfs":false,
- "options":{
- "include_fields":["_id","VERSION","ACCESSION","file"]
- }
- },
- "index":{
- "name":"indexname",
- "type":"meta"
- }
- }'
注: index 裏 name 爲索引名 要小寫,type 裏的meta 爲 collection name因爲本次測試使用的是mongodb sharding 集羣環境,因此在river鏈接時,使用mongos 路由,就可以正常的把mongo集羣中的全部數據都創建索引。gridfs,options 可不設置#curl 方式創建river (並創建resume索引)
curl -XPUT "localhost:9200/_river/tbJobResume/_meta" -d '
{
"type": "mongodb",
"mongodb": {
"host": "192.168.225.131",
"port": "37017",
"db": "MongoModelJobResume",
"collection": "tbJobResume"
},
"index": {
"name": "resume",
"type": "tbJobResume"} }'
說明:_river/tbJobResume tbJobResume 我用的是表名,建立每一個索引的時候最好不一樣 -d 後面的 '內容'兩個單引號不要丟了
type 後面是 mongodb 由於用的是 mongodb 數據庫mongodb: 分別是 ip,port,db(name),collection 就不用解釋了
index: name 要創建的索引名,最好是小寫(應該是必須)
index:type collection名,即該索引對應的數據集合名
驗證:
curl "http://localhost:9200/_river/tbJobResume/_meta"
這樣就建好了resume索引,mongodb若是有數據也會同步過來特別注意:若是tbJobResume表中有字段是地理座標,須要map成geo_point類型,在建立索引前設置mapping,以下:
curl -XPUT 'http://localhost:9200/resume' -d '
{
"mappings": {
"tbJobResume": {
"properties": {
"Location": {
"type": "geo_point"
}
}
}
}
}'設置完後在建立索引
---下面是建的另一個索引---
curl -XPUT "localhost:9200/_river/tbJobPosition/_meta" -d '
{
"type": "mongodb",
"mongodb": {
"host": "192.168.225.131",
"port": "37017",
"db": "MongoModelJob",
"collection": "tbJobPosition"
},
"index": {
"name": "position",
"type": "tbJobPosition"} }'
curl "http://localhost:9200/_river/tbJobPosition/_meta"---------------
#curl put索引數據
curl -XPUT "http://localhost:9200/customer/tbCustomer/1" -d'
{
"_id": 1,
"Name": "Francis Ford Coppola 1",
"Sex":1
}'
該方法會建立customer索引並put進一條數據,tbCustomer是type
curl -XPUT 'http://192.168.225.131:9200/dept/employee/32' -d '{ "empname": "emp32"}'
curl -XPUT 'http://192.168.225.131:9200/dept/employee/31' -d '{ "empname": "emp31"}'該方法也會建立dept索引並put進一條數據,employee是type
建立river並索引的變準模版以下:
$ curl -XPUT "localhost:9200/_river/${es.river.name}/_meta" -d '
{
"type": "mongodb",
"mongodb": {
"servers":
[
{ "host": ${mongo.instance1.host}, "port": ${mongo.instance1.port} },
{ "host": ${mongo.instance2.host}, "port": ${mongo.instance2.port} }
],
"options": {
"secondary_read_preference" : true,
"drop_collection": ${mongo.drop.collection},
"exclude_fields": ${mongo.exclude.fields},
"include_fields": ${mongo.include.fields},
"include_collection": ${mongo.include.collection},
"import_all_collections": ${mongo.import.all.collections},
"initial_timestamp": {
"script_type": ${mongo.initial.timestamp.script.type},
"script": ${mongo.initial.timestamp.script}
},
"skip_initial_import" : ${mongo.skip.initial.import},
"store_statistics" : ${mongo.store.statistics},
},
"credentials":
[
{ "db": "local", "user": ${mongo.local.user}, "password": ${mongo.local.password} },
{ "db": "admin", "user": ${mongo.db.user}, "password": ${mongo.db.password} }
],
"db": ${mongo.db.name},
"collection": ${mongo.collection.name},
"gridfs": ${mongo.is.gridfs.collection},
"filter": ${mongo.filter}
},
"index": {
"name": ${es.index.name},
"throttle_size": ${es.throttle.size},
"bulk_size": ${es.bulk.size},
"type": ${es.type.name}
"bulk": {
"actions": ${es.bulk.actions},
"size": ${es.bulk.size},
"concurrent_requests": ${es.bulk.concurrent.requests},
"flush_interval": ${es.bulk.flush.interval}
}
}
}'--template end--
--url--
本插件git地址:https://github.com/laigood/elasticsearch-river-mongodb
6 測試例子鏈接mongo集羣,meta collection數據量有22394792條數據
查看ES數據量
最後我在master1 master2 master3上都創建了ElasticSearch,而且3臺es rebalance成功,而且數據的總數任然爲22394792.