One-Way
爱一人,攀一山,追一梦

Elasticsearch

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

 

Elasticsearch Reference

参考文档:

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

 

ES安装

下载elasticsearch-2.2.0.tar.gz,解压,执行/bin/elasticsearch;

访问地址:http://node1:9200

 

安装插件 head

执行bin/plugin install mobz/elasticsearch-head

访问地址:http://node1:9200/_plugin/head

如果用root用户执行启动脚本会提示:

Exception in thread "main" java.lang.RuntimeException: don't run elasticsearch as root.

创建elasticsearch用户执行

adduser –U elasticsearch

然后以 elasticsearch用户登录,启动程序。

 

集群部署

部署三台机器,部署程序,然后修改配置文件 config/elasticsearch.yml

配置:

cluster.name: my-application
node.name: node1
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping_timeout: 120s
client.transport.ping_timeout: 60s
discovery.zen.ping.unicast.hosts: ["node1","node2", "node3"]

集群名字cluster.name相同才能组成一个集群,修改node.name对应的主机名。

 

防止脑裂配置

discovery.zen.minimum_master_nodes=2

 

Curl

通过curl操作Elasticsearch数据:

curl -XPUT ‘http://node1:9200/index1/’ -d ‘传输的数据’

-X指定http请求方法:HEAD, PUT, GET, PST, DELETE

-d 指定传输的数据

 

–GET:获取对象的当前状态;

–PUT:改变对象的状态;      幂等

–POST:创建对象;

–DELETE:删除对象;          幂等

–HEAD:获取头信息。

 

Elasticsearch与关系型数据库的对比

Database Index 
Table   Type
Row   Document
Column Field

 

 

 

 

 

创建Index

curl -XPUT 'http://node1:9200/test/'

 

创建Type

curl -XPOST http://node1:9200/test/emp/ -d '{"name" : "John"}' 自动创建id,也可以自己指定id
curl -XPUT http://node1:9200/test/emp/1 -d '{"name" : "Tom"}'  需要指定id

 

查询

curl -XGET http://node1:9200/test/emp/1
{"_index":"test","_type":"emp","_id":"1","_version":2,"found":true,"_source":{"name" : "Jim"}}
curl -XGET http://node1:9200/test/emp/1?pretty
{
  "_index" : "test",
  "_type" : "emp",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "name" : "Jim"
  }
}

pretty 格式化结果,更好看

 

查询带报文头

curl -i http://node1:9200/test/emp/1?pretty
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 134
{
  "_index" : "test",
  "_type" : "emp",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "name" : "Jim"
  }
}

 

查询_source

curl -XGET http://node1:9200/test/emp/1/_source
{"name" : "Jim"}

 

查询指定field的信息

curl -XGET http://node1:9200/test/emp/1?_source=name

 

查询type信息

curl -XGET http://node1:9200/test/emp/_search?pretty
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "test",
      "_type" : "emp",
      "_id" : "AVYw5zrHBTthl-73fXCK",
      "_score" : 1.0,
      "_source" : {
        "name" : "John"
      }
    }, {
      "_index" : "test",
      "_type" : "emp",
      "_id" : "2",
      "_score" : 1.0,
      "_source" : {
        "name" : "John"
      }
    }, {
      "_index" : "test",
      "_type" : "emp",
      "_id" : "1",
      "_score" : 1.0,
      "_source" : {
        "name" : "Jim"
      }
    } ]
  }
}

 

查询指定条件数据

curl -XGET http://node1:9200/test/emp/_search?q=name:Jim

 

 

Domain Specific Language DSL 查询

curl -XGET http://node1:9200/test/emp/_search?pretty -d  \
'{"query":
    {"match":
        {"name":"Jim"}
    }
}'

 

获取多个文档

curl -XGET http://node1:9200/_mget?pretty -d \
'{"docs":[{"_index":"test","_type":"emp","_id":1},{"_index":"test","_type":"emp","_id":2}]
}'
curl -XGET http://node1:9200/test/emp/_mget?pretty -d \
'{"ids":["1","2"]
}'

 

检查文档是否存在,只返回报文头

curl -i -XHEAD http://node1:9200/test/emp/1?pretty

 

更新字段信息

curl -XPUT http://node1:9200/test/emp/1?pretty -d \
'{"name":"Tom",}'

 

局部更新(增加first_name字段) 只能用POST

curl -XPOST http://node1:9200/test/emp/1/_update -d '{"doc":{"first_name":"Jim"}}'

 

删除文档

curl -XDELETE http://node1:9200/test/emp/1

指定id

 

查询设置 副本数量,分片数量

curl -XGET http://node1:9200/test/_settings?pretty
{
  "test" : {
    "settings" : {
      "index" : {
        "creation_date" : "1469698597831",
        "uuid" : "VFew5vmlQUC3Uieu62w23Q",
        "number_of_replicas" : "1",
        "number_of_shards" : "5",
        "version" : {
          "created" : "2020099"
        }
      }
    }
  }
}

 

设置分片及副本数

curl -XPUT http://node1:9200/test/_settings -d'{"settings":{"number_of_shards":3,"number_of_replicas":2}}'

 

查询mapping信息

curl -XGET http://node1:9200/test/_mapping?pretty

用于修改字段相关属性,如字段类型,是否使用分词器,使用哪种分词器

curl -XPOST http://node1:9200/test/emp/_mapping -d \
'{
    "emp": {
        "properties": {
              "name" : {
                "type" : "string",
                "analyzer" : "standard"
              }
        }
    }
}'

 

 

解析器

curl -XGET 'http://node1:9200/_analyze?analyzer=standard&pretty=true' -d '很高兴认识你'

使用解析器查看结果

具体说明参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/2.2/analyzer.html

 

Java API

官方文档:

https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.2/index.html

 

测试demo:

注意:这里使用term时注意使用小写,由于使用了分词器

  1 import org.elasticsearch.action.get.GetResponse;
  2 import org.elasticsearch.action.index.IndexResponse;
  3 import org.elasticsearch.action.search.SearchResponse;
  4 import org.elasticsearch.action.search.SearchType;
  5 import org.elasticsearch.client.Client;
  6 import org.elasticsearch.client.transport.TransportClient;
  7 import org.elasticsearch.common.settings.Settings;
  8 import org.elasticsearch.common.transport.InetSocketTransportAddress;
  9 import org.elasticsearch.common.unit.TimeValue;
 10 import org.elasticsearch.common.xcontent.XContentFactory;
 11 import org.elasticsearch.index.query.QueryBuilder;
 12 import org.elasticsearch.index.query.QueryBuilders;
 13 import org.elasticsearch.search.SearchHit;
 14 import org.junit.After;
 15 import org.junit.Before;
 16 import org.junit.Test;
 17 
 18 import java.io.IOException;
 19 import java.net.InetAddress;
 20 import java.net.UnknownHostException;
 21 
 22 /**
 23  * Created by Edward on 2016/7/29.
 24  */
 25 public class MyTest {
 26 
 27     public static Client client;
 28 
 29     @Before
 30     public void init() throws UnknownHostException {
 31         Settings settings = Settings.settingsBuilder()
 32                 .put("cluster.name", "my-application").build();
 33         client = TransportClient.builder().settings(settings).build()
 34                 .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node1"), 9300))
 35                 .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node2"), 9300))
 36                 .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("node3"), 9300));
 37     }
 38     @After
 39     public void closeClient()
 40     {
 41         client.close();
 42     }
 43 
 44     @Test
 45     public void createIndex() throws IOException {
 46         //创建索引
 47         IndexResponse response = client.prepareIndex("test", "emp", "1")
 48                 .setSource(XContentFactory.jsonBuilder()
 49                         .startObject()
 50                         .field("name", "Tom")
 51                         .field("age", "21")
 52                         .field("message", "Elasticsearch")
 53                         .endObject())
 54                 .get();
 55         System.out.println(response);
 56     }
 57 
 58     @Test
 59     public void queryIndex(){
 60         //获取索引信息
 61         GetResponse res = client.prepareGet("test", "emp", "1").get();
 62         System.out.println(res.getSource());
 63     }
 64 
 65     @Test
 66     public void search(){
 67 
 68         SearchResponse response = client.prepareSearch("test")
 69                 .setTypes("emp")
 70                 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
 71                 //注意term使用了分词,这里tom使用小写
 72                 .setQuery(QueryBuilders.termQuery("name", "tom"))                 // Query
 73                 //.setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))     // Filter
 74                 //.setFrom(0).setSize(60).setExplain(true)
 75                 .execute()
 76                 .actionGet();
 77         System.out.println(response.getHits().getHits().length);
 78         //SearchResponse response = client.prepareSearch().execute().actionGet();
 79         System.out.println(response.toString());
 80     }
 81 
 82 
 83     @Test
 84     public void scrollQuery(){
 85 
 86         //注意由于使用了分词,这里tom使用小写
 87         QueryBuilder qb = QueryBuilders.termQuery("name", "tom");
 88 
 89         SearchResponse scrollResp = client.prepareSearch("test")
 90                 .setTypes("emp")
 91                 .setSearchType(SearchType.SCAN)
 92                 .setScroll(new TimeValue(60000))
 93                 .setQuery(qb)
 94                 .setSize(100).execute().actionGet(); //100 hits per shard will be returned for each scroll
 95 //Scroll until no hits are returned
 96         while (true) {
 97             scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
 98             for (SearchHit hit : scrollResp.getHits().getHits()) {
 99                 //Handle the hit...
100                 System.out.println(hit.getSource());
101             }
102 
103             //Break condition: No hits are returned
104             if (scrollResp.getHits().getHits().length == 0) {
105                 break;
106             }
107         }
108     }
109 }
posted on 2016-08-01 14:27  单行道|  阅读(1973)  评论(0编辑  收藏  举报