首页 > 技术文章 > ElasticSearch的基本认识和基本操作

xiaohuziguai 2019-04-27 15:26 原文

1.1.  ElasticSearch(简称ES)

ES即为了解决原生Lucene使用的不足,优化Lucene的调用方式,并实现了高可用的分布式集群的搜索方案,其第一个版本于2010年2月出现在GitHub上并迅速成为最受欢迎的项目之一。

ES的核心不在于Lucene,其特点更多的体现为:

分布式的实时文件存储,每个字段都被索引并可被搜索

分布式的实时分析搜索引擎

可以扩展到上百台服务器,处理PB级结构化或非结构化数据

高度集成化的服务,你的应用可以通过简单的 RESTful API、各种语言的客户端甚至命令行与之

交互。

上手Elasticsearch非常容易。它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它拥有开瓶即饮的效果(安装即可使用),只需很少的学习既可在生产环境中使用。

和ES类似的框架

Solr

Solr和ES比较:

Solr 利用 Zookeeper 进行分布式管理,支持更多格式的数据(HTML/PDF/CSV),官方提供的功能更多在传统的搜索应用中表现好于 ES,但实时搜索效率低。

 ES自身带有分布式协调管理功能,但仅支持json文件格式,本身更注重于核心功能,高级功能多有第三方插件提供,在处理实时搜索应用时效率明显高于 Solr。

Katta

基于 Lucene 的,支持分布式,可扩展,具有容错功能,准实时的搜索方案。

优点:开箱即用,可以与 Hadoop 配合实现分布式。具备扩展和容错机制。

缺点:只是搜索方案,建索引部分还是需要自己实现。在搜索功能上,只实现了最基本的需求。成功案例较少,项目的成熟度稍微差一些。

HadoopContrib

Map/Reduce 模式的,分布式建索引方案,可以跟 Katta 配合使用。

优点:分布式建索引,具备可扩展性。

缺点:只是建索引方案,不包括搜索实现。工作在批处理模式,对实时搜索的支持不佳。

 ES数据管理

创建索引文档

①使用自己的ID创建:

PUT {index}/{type}/{id}

{

"field": "value",

  ...

}

局部更新文档

接受一个局部文档参数 doc,它会合并到现有文档中,对象合并在一起,存在的标量字段被覆盖,新字段被添加。

POST itsource/employee/123/_update

{

“doc”:{

"email" : "nixianhua@itsource.cn",

"salary": 1000

 

}

}

删除文档

DELETE {index}/{type}/{id}

批量操作bulk  API

使用单一请求来实现多个文档的createindexupdate delete

Bulk请求体格式:

{ action: { metadata }}\n

{ request body }\n

{ action: { metadata }}\n

{ request body }\n

POST _bulk
{ "delete": { "_index": "itsource", "_type": "employee", "_id": "123" }}
{ "create": { "_index": "itsource", "_type": "blog", "_id": "123" }}
{ "title": "我发布的博客" }
{ "index": { "_index": "itsource", "_type": "blog" }}
{ "title": "我的第二博客" }

 

批量获取

#批量获取方式一
GET _mget
{
  "docs":[{
      "_index":"itsource",
      "_type":"blog",
      "_id":"123"
    },{
       "_index":"itsource",
      "_type":"blog",
      "_id":"AWpXiEfhCq6ubXlpA9Ia",
      "_source":"title"
      
    }]
}

#批量获取方式二
GET itsource/blog/_mget
{
  "ids":["123","AWpXiEfhCq6ubXlpA9Ia"]
}

分页查询

#分页查询
GET _search?size=3&from=2;
//查询条件位欸age=18的  
GET crm/employees/_search?q=age:18
//查询10>age<30
GET crm/employees/_search?q=age[10 TO 30]

DSL查询

#DSL的查询方式
GET crm/employees/_search
{
"query" : {
    "match" : {
          "name" : "大哥"
   }
  }
}

案例:类似京东网站 查询关键字为iphone,国家为us的,价格范围6000到8000 价格降序,并# 且取前面2条:

GET shop/goods/_search
{
  "query":{
    "bool": {
      "must": [
        {"match": {
          "name": "iphone"
        }}
      ],
      "filter": [{
        "term":{
          "local":"us"
        }
      },{
        "range":{
          "price":{
            "gte":"5000",
            "lte":"7000"
          }
        }
      }]
    }
  },
  "from": 1,
  "size": 5,
  "_source": ["id", "name", "type","price"],
  "sort": [{"price": "desc"}]
  

在java中的操作为

  1 public class elasticTest {
  2 
  3     //取得clean对象
  4     public TransportClient getClient() throws UnknownHostException {
  5         TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
  6                 .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
  7         return client;
  8 
  9     }
 10     //添加数据
 11     @Test
 12     public void getCreated() throws Exception {
 13         TransportClient client = getClient();
 14         //创建一个库
 15         IndexRequestBuilder indexRequestBuilder = client.prepareIndex("crm", "user", "1");
 16         //准备数据
 17         Map<String, Object> mp = new HashMap();
 18         mp.put("id", 2);
 19         mp.put("name", "kg");
 20         mp.put("age", 18);
 21         //将数据放入到库中,并且将数据读取出来
 22         IndexResponse indexResponse = indexRequestBuilder.setSource(mp).get();
 23         System.out.println(indexResponse);
 24     }
 25     //修改数据
 26     @Test
 27         public void update() throws Exception{
 28         TransportClient client = getClient();
 29         Map mp=new HashMap();
 30         mp.put("id", 2);
 31         mp.put("name", "黄巢");
 32         mp.put("age", 35);
 33         UpdateResponse response = client.prepareUpdate("crm", "user", "1").setDoc(mp).get();
 34         GetResponse fields = client.prepareGet("crm", "user", "1").get();
 35         System.out.println(fields.getSource());
 36 
 37 
 38 
 39     }
 40     //进行删除
 41     @Test
 42         public void testdelete() throws Exception{
 43         TransportClient client = getClient();
 44         DeleteResponse response = client.prepareDelete("crm", "user", "1").get();
 45         System.out.println(response);
 46     }
 47         //批量添加
 48     @Test
 49         public void BUlk() throws Exception{
 50         TransportClient client = getClient();
 51         BulkRequestBuilder bulk = client.prepareBulk();
 52         for (int i=0;i<10;i++){
 53             Map map=new HashMap();
 54             map.put("id", i);
 55             map.put("age", 6+i);
 56             map.put("name", "zhansan"+i);
 57 
 58             bulk.add(client.prepareIndex("crm","suer",i+"").setSource(map));
 59         }
 60         BulkResponse response = bulk.get();
 61 
 62         SearchRequestBuilder search = client.prepareSearch("crm", "suer");
 63         System.out.println(search);
 64 
 65 
 66         if (response.hasFailures()){
 67             System.out.println("err");
 68         }
 69     client.close();
 70     }
 71 
 72 
 73     @Test
 74         public void testQuery() throws Exception{
 75         TransportClient client = getClient();
 76         BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
 77         //匹配值
 78         List<QueryBuilder> must = boolQuery.must();
 79         must.add(QueryBuilders.termQuery("name", "zhansan1"));
 80 
 81         //过滤
 82         List<QueryBuilder> filter = boolQuery.filter();
 83         filter.add(QueryBuilders.rangeQuery("age").gte("6").lte(10));
 84 
 85         //设置分页
 86         SearchResponse response = client.prepareSearch("crm")
 87                 .setFrom(0).setSize(3)
 88                 .setQuery(boolQuery)
 89                 .addSort("id", SortOrder.DESC).get();
 90 
 91         System.out.println("总条数"+response.getHits().getTotalHits());
 92         //第一次gethits表示获取到命中条数,第二次表示获取得到命中条数的数组
 93         SearchHit[] hits = response.getHits().getHits();
 94         //遍历数组得到具体的值
 95         for (SearchHit hit : hits) {
 96             System.out.println(hit.getSource());
 97         }
 98 
 99     }
100 }

 

推荐阅读