Elasticsearch 初入門
Elasticsearch 與關系型數據庫的對比:
Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields
Elasticsearch 當中的 Indices 相當于 Databases,Types 相當于 Tables, Documents 相當于 Rows,Fields 相當于 Columns。
與 Elasticsearch 交互
使用 Java api 與 Elasticsearch 交互的時候有兩種方式:
節點客戶端(node client)
節點客戶端以無數據節點(none data node)身份加入集群,換言之,它自己不存儲任何數據,但是它知道數據在集群中的具體位置,并且能夠直接轉發請求到對應的節點上。
import static org.elasticsearch.node.NodeBuilder.*; // on startup Node node = nodeBuilder().client(true).node(); Client client = node.client(); // on shutdown node.close();
當你啟動一個node,它就加入了elasticsearch集群。你可以通過簡單的設置 cluster.name 或者明確地使用 clusterName 方法擁有不同的集群。
一種是在 classpath 下添加 elasticsearch.yml 文件并且指定了cluster.name: yourclustername,另外一種方式就是如下的 Java 當中指定。
Node node = nodeBuilder().clusterName("yourclustername").node();
Client client = node.client();利用Client的好處是,操作可以自動地路由到這些操作被執行的節點,而不需要執行雙跳(double hop)。例如,索引操作將會在該操作最終存在的分片上執行。
傳輸客戶端(transport client)
TransportClient 利用 transport 模塊遠程連接一個 elasticsearch 集群。它并不加入到集群中,只是簡單的獲得一個或者多個初始化的 transport 地址,并以輪詢的方式與這些地址進行通信。
// on startup
Client client = new TransportClient()
.addTransportAddress(new InetSocketTransportAddress("host1", 9300))
.addTransportAddress(new InetSocketTransportAddress("host2", 9300));
// on shutdown
client.close();
Settings settings = ImmutableSettings.settingsBuilder()
.put("cluster.name", "myClusterName").build();//指定集群的名字
Client client = new TransportClient(settings);多網段集群
discovery.zen.ping.multicast.enabled: false #禁用默認的廣播方式 discovery.zen.ping.unicast.hosts: [“10.168.202.3″, “10.168.205.81”] #指定node1和node2的地址
在相同網段的 node 并且集群名字相同的時候可以組成一個集群,如果不在一個網段我們可以如上指定集群機器的地址。
建議指定機器地址配置集群,避免產生無意組成集群的尷尬或者網段變動找不到 node 的尷尬。
Elasticsearch Restful 操作
使用 httpie 來在終端操作 http 請求。
查看所有索引:
http get :9200/_cat/indices yellow open index 5 1 2 0 7.8kb 7.8kb yellow open gb 5 1 7 0 20.4kb 20.4kb yellow open us 5 1 7 1 19.6kb 19.6kb yellow open my_store 5 1 4 0 13.5kb 13.5kb
創建索引:
http put :9200/testindex
{
"acknowledged": true
}創建文檔:
http post :9200/testindex/user name="rcx" age="19"
{
"_id": "AVGuBqaBqxzGIsNTwSSo",
"_index": "testindex",
"_shards": {
"failed": 0,
"successful": 1,
"total": 2
},
"_type": "user",
"_version": 1,
"created":上面創建文檔的時候沒有指定 id,那么 ES 就會自動生產一個 id,我們也可以指定 id 創建文檔:
http post :9200/testindex/user/2 name="rcx2" age="29"
{
"_id": "2",
"_index": "testindex",
"_shards": {
"failed": 0,
"successful": 1,
"total": 2
},
"_type": "user",
"_version": 1,
"created": true
}獲取文檔:
http get :9200/testindex/user/2
{
"_id": "2",
"_index": "testindex",
"_source": {
"age": "29",
"name": "rcx2"
},
"_type": "user",
"_version": 1,
"found": true
}刪除文檔:
http delete :9200/testindex/user/AVGuBqaBqxzGIsNTwSSo
{
"_id": "AVGuBqaBqxzGIsNTwSSo",
"_index": "testindex",
"_shards": {
"failed": 0,
"successful": 1,
"total": 2
},
"_type": "user",
"_version": 2,
"found": true
}更新文檔:
http put :9200/testindex/user/2 name="name2"
{
"_id": "2",
"_index": "testindex",
"_shards": {
"failed": 0,
"successful": 1,
"total": 2
},
"_type": "user",
"_version": 2,//版本變成了2
"created": false
}局部更新:在文檔后面添加 _update 并且需要修改的字段在 doc 里面。
http post :9200/testindex/user/2/_update doc:='{"name":"upname","title":"a title"}'
{
"_id": "2",
"_index": "testindex",
"_shards": {
"failed": 0,
"successful": 1,
"total": 2
},
"_type": "user",
"_version": 5
}
http get :9200/testindex/user/2
{
"_id": "2",
"_index": "testindex",
"_source": {
"age": "25",
"name": "upname",
"title": "a title"
},
"_type": "user",
"_version": 5,
"found": true
}檢索多個文檔:
http get :9200/testindex/user/_mget docs:='[{"_id":1},{"_id":2}]'
{
"docs": [
{
"_id": "1",
"_index": "testindex",
"_source": {
"age": "19",
"name": "rcx1",
"title": "安師大"
},
"_type": "user",
"_version": 1,
"found": true
},
{
"_id": "2",
"_index": "testindex",
"_source": {
"age": "25",
"name": "upname",
"title": "a title"
},
"_type": "user",
"_version": 5,
"found": true
}
]
}【參考資料】
---EOF---