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": true }
上面创建文档的时候没有指定 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 } ] }
【参考资料】
- Elasticsearch 权威指南
---EOF---