ElasticSearch 实践

版本:2.3.5

版本:5.3.0 (应为3.X,随ELK版本统一,故从5.X 开始)

Windows端

1、官网下载

https://www.elastic.co/downloads/past-releases/elasticsearch-2-3-5

2、安装head插件

进入目录E:\elasticsearch-2.3.5\bin>

执行

plugin.bat install mobz/elasticsearch-head


安装完毕

3、启动

E:\elasticsearch-2.3.5\bin>elasticsearch.bat

 

验证(安装curl,注意windows cmd中使用curl不能换行,所以采用cygwin + curl 解决)

可参考:http://blog.csdn.net/carlwu/article/details/53535954

问题:加入环境变量或放入system32目录

1、

C:\Users\Administrator>curl "http://localhost:9200/?pretty"
{
  "name" : "Bishop",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.3.5",
    "build_hash" : "90f439ff60a3c0f497f91663701e64ccd01edbb4",
    "build_timestamp" : "2016-07-27T10:36:52Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.0"
  },
  "tagline" : "You Know, for Search"
}


注意Windows 地址可以不需要引号或使用双引号;

2、访问 http://localhost:9200/_plugin/head/

安装成功!

4、测试

自定义索引信息

索引名:zhou;索引类型:shun;字段:(userName,age,car)

创建索引:

C:\Users\Administrator>curl -XPUT http://localhost:9200/zhou/
{"acknowledged":true}
C:\Users\Administrator>curl -XGET http://localhost:9200/zhou/?pretty
{
  "zhou" : {
    "aliases" : { },
    "mappings" : { },
    "settings" : {
      "index" : {
        "creation_date" : "1491795195654",
        "uuid" : "8KtP-8HCR9er7bnsAlbbbw",
        "number_of_replicas" : "1",
        "number_of_shards" : "5",
        "version" : {
          "created" : "2030599"
        }
      }
    },
    "warmers" : { }
  }
}
"number_of_replicas" : "1",
        "number_of_shards" : "5",
        "version" : {
          "created" : "2030599"
        }
      }
    },
    "warmers" : { }
  }
}

标红处可看到索引默认的分片和副本分别为5和1

创建索引时 可以指定分片和副本

JSON:

C:\Users\Administrator>curl -XPUT http://localhost:9200/zhou/ -d {"settings":{"index":{"number_of_shards":3,"number_of_r
eplicas":2}}}
{"acknowledged":true}
C:\Users\Administrator>curl http://localhost:9200/zhou/?pretty
{
  "zhou" : {
    "aliases" : { },
    "mappings" : { },
    "settings" : {
      "index" : {
        "creation_date" : "1491807780791",
        "uuid" : "9n2r_fUVSXO53CKKgYOcnw",
        "number_of_replicas" : "2",
        "number_of_shards" : "3",
        "version" : {
          "created" : "2030599"
        }
      }
    },
    "warmers" : { }
  }
}

由于Windows Dos 不支持换行符,so

curl -XPUT http://localhost:9200/zhou/ -d 
index:
  number_of_shards:3
  number_of_replicas:2

索引mapping,创建了索引类型为shun 的 映射结构

$ curl -XPUT http://localhost:9200/zhou/_mappings/shun?pretty -d '
> {
>     "properties":{
>         "userName":{
>             "type":"string",
>             "index":"analyzed"
>         },
>         "age":{
>             "type":"integer",
>             "fields":{
>                 "age":{
>                     "type":"integer"
>                 },
>                 "raw":{
>                     "type":"string",
>                     "index":"not_analyzed"
>                 }
>             }
>         },
>         "car":{
>             "type":"string",
>             "index":"analyzed"
>         }
>     }
> } '
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   532  100    28  100   504    595  10723 --:--:-- --:--:-- --:--:-- 10723{
  "acknowledged" : true
}

索引插入:PUT因为幂等性,适用于指定主键插入,等同于全量更新;POST 指定主键,自动主键均可

自动主键

$ curl XPOST 'http://localhost:9200/zhou/shun?pretty' -d '
{
    "userName":"zhou shun",
    "age":10,
    "car":[
        "benz",
        "bmw"
    ]
}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   287  100   193  100    94   1026    500 --:--:-- --:--:-- --:--:--  1026{
  "_index" : "zhou",
  "_type" : "shun",
  "_id" : "AVtW9_74Wik3CeNre3WI",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}

指定主键:

$ curl -XPUT 'localhost:9200/zhou/shun/9999?pretty' -d '{
"userName":"bva","age":55,"car":"bbbbb"}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   219  100   177  100    42   2809    666 --:--:-- --:--:-- --:--:--  2809{
  "_index" : "zhou",
  "_type" : "shun",
  "_id" : "9999",
  "_version" : 1,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "created" : true
}

查询

全量:

$ curl 'http://localhost:9200/zhou/shun/_search?pretty'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   638  100   638    0     0    638      0  0:00:01 --:--:--  0:00:01  623k{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "AVtW96QWWik3CeNre3WH",
      "_score" : 1.0,
      "_source" : {
        "userName" : "zhou shun",
        "age" : 10,
        "car" : [ "benz", "bmw" ]
      }
    }, {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "1",
      "_score" : 1.0,
      "_source" : {
        "userName" : "zs.zhou",
        "age" : 10,
        "car" : [ "benz", "bmw" ]
      }
    } ]
  }
}

查询索引zhou下所有

$ curl 'http://localhost:9200/zhou/_search?pretty'、

查询所有索引库

$ curl 'http://localhost:9200/_search?pretty'

根据ID:

$ curl 'http://localhost:9200/zhou/shun/1?_source&pretty'

$ curl 'http://localhost:9200/zhou/shun/1/_source&pretty' 

$ curl 'http://localhost:9200/zhou/shun/1?pretty'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   190  100   190    0     0   5937      0 --:--:-- --:--:-- --:--:-- 11875{
  "_index" : "zhou",
  "_type" : "shun",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "userName" : "zs.zhou",
    "age" : 10,
    "car" : [ "benz", "bmw" ]
  }
}

根据条件查询:

$ curl -XGET http://localhost:9200/zhou/shun/_search?q=userName:zs
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   122  100   122    0     0   7625      0 --:--:-- --:--:-- --:--:--  119k{"took":1,"timed_out":false,"_shards":{"total":3,"successful":3,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

发现查询不出数据,但有userName为 zs.zhou的,后来了解到 和数据库的like操作不一样,

es,lucene使用的分词引擎是根据拆分的词项进行匹配的。当然,zs.zhou是个完整的词。

zhou shun 由于分词后 为 zhou 和 shun ,故能查询到。

Administrator@PC-20150504VJBV ~
100   314  100   314    0     0    314      0  0:00:01 --:--:--  0:00:01  306k{"took":3,"timed_out":false,"_shards":{"total":3,"successful":3,"failed":0},"hits":{"total":1,"max_score":0.19178301,"hits":[{"_index":"zhou","_type":"shun","_id":"AVtW96QWWik3CeNre3WH","_score":0.19178301,"_source":
{
    "userName":"zhou shun",
    "age":10,
    "car":[
        "benz",
        "bmw"
    ]
}}]}}

[1]+  已完成               curl -XGET http://localhost:9200/zhou/shun/_search?q=userName:zhou

那么zs.zhou应该怎么实现和数据库一样的like查询效果呢?

使用wildcard 通配符查询:

Administrator@PC-20150504VJBV ~
100   279  100   279    0     0    279      0  0:00:01 --:--:--  0:00:01  272k{"took":3,"timed_out":false,"_shards":{"total":3,"successful":3,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"zhou","_type":"shun","_id":"1","_score":1.0,"_source":
{
    "userName":"zs.zhou",
    "age":10,
    "car":[
        "benz",
        "bmw"
    ]
}}]}}

[1]+  已完成               curl -XGET http://localhost:9200/zhou/shun/_search?q=userName:zs*

Administrator@PC-20150504VJBV ~

部分更新:

更新ID = 1的文档的 age字段 。 注:doc为关键字

Administrator@PC-20150504VJBV ~
$ curl -XPOST http://localhost:9200/zhou/shun/1/_update -d '
{"doc":{"age":20}}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   122  100   103  100    19   1320    243 --:--:-- --:--:-- --:--:--  1320{"_index":"zhou","_type":"shun","_id":"1","_version":3,"_shards":{"total":2,"successful":1,"failed":0}}

或全量更新 (其余字段会被置空,需指明所有字段)

Administrator@PC-20150504VJBV ~
$ curl -XPUT http://localhost:9200/zhou/shun/1 -d '
{"age":30}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   130  100   119  100    11   1919    177 --:--:-- --:--:-- --:--:--  1919{"_index":"zhou","_type":"shun","_id":"1","_version":4,"_shards":{"total":2,"successful":1,"failed":0},"created":false}

或根据script脚本语言

全量更新,其实就是利用PUT的幂等性 进行数据的覆盖

Administrator@PC-20150504VJBV ~
$ curl -XPUT http://localhost:9200/zhou/shun/1 -d '
{"userName" : "zs.zhou leo.li " ,"age":109}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   163  100   119  100    44    691    255 --:--:-- --:--:-- --:--:--   691{"_index":"zhou","_type":"shun","_id":"1","_version":7,"_shards":{"total":2,"successful":1,"failed":0},"created":false}

根据_id删除:

$ curl -XDELETE 'http://localhost:9200/zhou/shun/AVtW9_74Wik3CeNre3WI'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   135  100   135    0     0   2177      0 --:--:-- --:--:-- --:--:--  2177{"found":true,"_index":"zhou","_type":"shun","_id":"AVtW9_74Wik3CeNre3WI","_version":2,"_shards":{"total":2,"successful":1,"failed":0}}

根据条件删除,需要用到DSL,使用_query替换_search达到搜索条件的目的(測試后發現不一定有作用)

注:还是需要使用_search + DSL,经测试 _query无效

Administrator@PC-20150504VJBV ~
$ curl -XDELETE 'localhost:9200/zhou/shun/_query?pretty' -d '
{
  "query": { "match": { "age": 555 } }
}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   220  100   177  100    43   1609    390 --:--:-- --:--:-- --:--:--  1609{
  "found" : true,
  "_index" : "zhou",
  "_type" : "shun",
  "_id" : "_query",
  "_version" : 3,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

批处理(bulk):

batch文件,默认使用换行符作为完整一行命令的结束 ,以下二行为完整一条命令

{"index":{"_index":"zhou","_type":"shun"}}
{"userName":"Peter BisShop","age":101,"car":"buick"}
{"create":{"_index":"zhou","_type":"shun","_id":"1"}}
{"userName":"Amy acker","age":40,"car":["volkswagen","mini cooper"]}
{"delete":{"_index":"zhou","_type":"shun","_id":"AVtX_zfDJD8Lt5ZvIw3A"}
{"update":{"_index":"zhou","_type":"shun","_id":"AVtYAQ2RJD8Lt5ZvIw3E"}}
{"doc":{"age":9999}}

200:success;201:created

Administrator@PC-20150504VJBV /doc
$ curl -XPUT 'http://localhost:9200/_bulk?pretty' --data-binary @batch
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1478  100  1086  100   392   3166   1142 --:--:-- --:--:-- --:--:--  3310{
  "took" : 335,
  "errors" : false,
  "items" : [ {
    "create" : {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "AVtYGcfTUuqDCgrXO2Ka",
      "_version" : 1,
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "status" : 201
    }
  }, {
    "create" : {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "1",
      "_version" : 1,
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "status" : 201
    }
  }, {
    "delete" : {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "AVtX_zfDJD8Lt5ZvIw3A",
      "_version" : 2,
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "status" : 200,
      "found" : true
    }
  }, {
    "update" : {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "AVtYAQ2RJD8Lt5ZvIw3E",
      "_version" : 2,
      "_shards" : {
        "total" : 2,
        "successful" : 1,
        "failed" : 0
      },
      "status" : 200
    }
  } ]
}

复制一段DSL的描述

DSL:elasticsearch 提供基于JSON的完整的Query DSL查询表达式(DSL即领域专用语言). 一般来说, 普通的查询如 term 或者 prefix. 另外还有混合查询如 bool 等. 另外查询表达式(Queries)还能够关联特定的过滤表达式,如 filtered 或者 constant_score 查询.
你可以把Query DSL当作是一系列的抽象的查询表达式树( AST ). 特定查询能够包含其它的查询,(如 bool ), 有些查询能够包含过滤器(如 constant_score), 还有的可以同时包含查询和过滤器 (如 filtered). 都能够从ES支持查询集合里面选择任意一个查询或者是从过滤器集合里面挑选出任意一个过滤器, 这样的话,我们就可以构造出任意复杂(maybe 非常有趣)的查询了,是不是很灵活啊.
查询和过滤都可以被用于各种不同的API接口里面. 如 search query, 或者是 facet filter 等等. 

提示. 过滤器非常有用因为他们比简单的查询更快(不进行文档评分)并且会自动缓存.

使用过滤器查询(query查询json保存在文件中)

query.json:过滤名字中有amy词项的记录

{
    "query":{
        "filtered":{
            "query":{
                "match":{
                    "userName":"amy"
                }
            },
            "filter":{
                "range":{
                    "age":{
                        "gte":30
                    }
                }
            }
        }
    }
}

 

Administrator@PC-20150504VJBV /doc
$ curl localhost:9200/zhou/shun/_search?pretty -d @query.json
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   501  100   431  100    70   4634    752 --:--:-- --:--:-- --:--:--  4634{
  "took" : 64,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.058217,
    "hits" : [ {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "1",
      "_score" : 1.058217,
      "_source" : {
        "userName" : "Amy acker",
        "age" : 40,
        "car" : [ "volkswagen", "mini cooper" ]
      }
    } ]
  }
}

查询:

Administrator@PC-20150504VJBV /doc
$ curl -XGET localhost:9200/zhou/shun/_search?pretty -d '{
"size":3,"from":0,"sort":{"age":{"order":"asc"}},"query":
{"match":{"userName":"Peter"}
}
}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   967  100   874  100    93    874     93  0:00:01 --:--:--  0:00:01  853k{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "failed" : 0
  },
  "hits" : {
    "total" : 7,
    "max_score" : null,
    "hits" : [ {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "44",
      "_score" : null,
      "_source" : {
        "userName" : "Peter BisShop",
        "age" : 44
      },
      "sort" : [ 44 ]
    }, {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "AVtYAQ2RJD8Lt5ZvIw3E",
      "_score" : null,
      "_source" : {
        "userName" : "Peter",
        "age" : 51
      },
      "sort" : [ 51 ]
    }, {
      "_index" : "zhou",
      "_type" : "shun",
      "_id" : "AVtYADkNJD8Lt5ZvIw3C",
      "_score" : null,
      "_source" : {
        "userName" : "Peter BisShop",
        "age" : 101,
        "car" : "buick"
      },
      "sort" : [ 101 ]
    } ]
  }
}

Java端,默认client端口为 9300

package elasticSearch;

import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.bootstrap.Elasticsearch;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;

import java.net.InetAddress;
import java.util.*;

/**
 * Created by Administrator on 2017/4/17.
 */
public class ElasticSearch {

    private static TransportClient client   = null;

    /**
     * es index
     */
    private static final String    ES_INDEX = "zhou";
    /**
     * es type
     */
    private static final String    ES_TYPE  = "shun";

    public static void main(String[] args) throws Exception {
        String aaa = new String("abc");
        String bbb = "abc";
        String ccc = "abc";

        System.out.println(aaa==bbb);
        System.out.println(ccc==bbb);
        System.out.println(aaa==ccc);

        createClient();

        String _id = createIndex();

        getDataResponse(_id);

        updateData(_id);

        getDataResponse(_id);

        QueryBuilder builder = QueryBuilders.matchAllQuery();
        // QueryBuilder builder = QueryBuilders.termQuery("username", "zhengyong");
        queryDataList(builder);

        // deleteDataResponse(_id);

        shutdown();
    }

    private static void createClient() throws Exception {
        if (client == null) {
            synchronized (ElasticSearch.class) {
//                Settings settings = Settings.settingsBuilder().put("cluster.name", "myCluster").build();
//                client = TransportClient.builder().settings(settings).build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),
//                        9200));

                Settings settings = Settings.settingsBuilder().put("cluster.name", "myCluster").build();
                client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),
                        9300));
            }
        }
    }

    /**
     * 创建es库并导入数据
     *
     * @return _id
     */
    private static String createIndex() {
        String json = "{" + "\"userName\":\"zzs\"," + "\"age\":" + 1056 + "}";

        System.out.println(json);
        IndexResponse response = client.prepareIndex(ES_INDEX, ES_TYPE).setSource(json).get();

        if(response.isCreated()){
            System.out.println(response.getId());
        }

        return response.getId();
    }

    /**
     * 根据_id获取数据
     *
     * @param _id 唯一标识
     * @return GetResponse
     */
    private static GetResponse getDataResponse(String _id) {
        GetResponse response = client.prepareGet(ES_INDEX, ES_TYPE, _id).get();
        System.out.println(String.format("get data response: %s", JSON.toJSONString(response.getSource())));
        return response;
    }

    /**
     * 根据查询条件查询结果集
     *
     * @param queryBuilder 查询条件
     * @return List
     */
    private static List<String> queryDataList(QueryBuilder queryBuilder) {
        SearchResponse sResponse = client.prepareSearch(ES_INDEX).setTypes(ES_TYPE).setQuery(queryBuilder).setSize(1000).execute().actionGet();
        SearchHits hits = sResponse.getHits();

        List<String> list = new ArrayList<>();
        SearchHit[] hitArray = hits.hits();
        for (SearchHit hit : hitArray) {
            Map<String, Object> map = hit.getSource();

            String username = (String) map.get("userName");
            Integer age = (Integer) map.get("age");

            StringBuilder br = new StringBuilder();
            br.append(username).append("_").append(age).append("_");
            list.add(br.toString());
        }

        System.out.println(String.format("query data count=%s, list : %s", list.size(), JSON.toJSONString(list)));

        return list;
    }

    /**
     * 根据_id删除数据
     *
     * @param _id 唯一标识
     * @return DeleteResponse
     */
    private static DeleteResponse deleteDataResponse(String _id) {
        DeleteResponse response = client.prepareDelete(ES_INDEX, ES_TYPE, _id).get();
        System.out.println(String.format("delete data response: %s", JSON.toJSONString(response)));
        return response;
    }

    /**
     * 根据_id跟下数据
     *
     * @param _id 唯一标识
     * @throws Exception
     */
    private static void updateData(String _id) throws Exception {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index(ES_INDEX);
        updateRequest.type(ES_TYPE);
        updateRequest.id(_id);

        String json = "{" + "\"userName\":\"zzs_update\"," + "\"age\":" + 2056 + "}";

        updateRequest.doc(json);

        client.update(updateRequest).get();
    }

    private static void shutdown() {
        if (client != null) {
            client.close();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值