美文网首页
ES-查询搜索篇

ES-查询搜索篇

作者: 靈08_1024 | 来源:发表于2018-05-24 17:29 被阅读50次
REST介绍

REST(REpresentational State Transfer),字面意思为“表述性状态传输”,一种开发的约定。
REST约定用HTTP的请求头POST、GET、PUT、DELETE正好对应CRUD(Create、Read、Update、Delete)四种数据操作。

索引、映射的建立

索引的建立:

curl -X PUT http://localhost:9200/hospital/

{
  "settings": {
    "number_of_shards": 1,//分片数量
    "number_of_replicas": 0//副本分片数量
  }
}

映射的建立:

curl -X PUT http://localhost:9200/hospital/_mapping/medicine2?pretty

{
    "dynamic": false,
    "properties": {
      "standardName": {
        "type": "text",
        "index": "analyzed"
      },
      "pattern": {
        "type": "text"
      },
     "validDate": {
        "type": "keyword"
      }
    }
}

1、DSL篇

可以在java中输出SearchQueryBuilder,来查看对应的DSL(json格式)。

在ES中进行查询,默认的分词器对于单个汉字都会进行分词,标点符号不计入分词,以空格来间隔英语单词。对于not_analyzed不计入分词器,只能全部搜索(或者用通配符查询、前缀查询)。对于计入分词的,term、match*(match系列)、querystring都支持,而且查询比较良好。keyword或者数字类型,都只支持整个匹配。

说一说分页,分页都深度分页和游标分页。
深度分页是每一次都会从最新的数据中进行查询。适合于实时查询分页。因为深度分页与CPU、IO、带宽、内存都有关。所以需要限制深度分页的页数,防止因为以上原因(或爬虫)造成卡顿或者宕机。
游标分页是在你查询时,会初始化一个快照,在遍历时,从这个快照里取数据,也就是说,在初始化后对索引插入、删除、更新数据都不会影响遍历结果。适用于后端对于数据的大批量分析。

2、JAVA篇

以下所有的方法都写重点部分,需要样例,请参见GitHub:https://github.com/lingbao08/springboot-example.git

1. 创建查询容器
//此容器可以放置所有的queryBuilder
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
1. 查询字符串
//精确查询,查询有该分词的文档
QueryBuilder termQuery = QueryBuilders.termQuery(field, value);
//字符串查询,查询包含该分词的文档(英文只针对于单词,中文可能会拆开该词语:策略视分词器而定)
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value)
             .field(field,2f);//可以指定单字段,也可以不指定,不指定按照默认字段查询
//              .fields(map)//多个字段
2.查询范围值
//可以只选大于而不选小于。可以用于查询日期、数字、字符串等。
//比较日期时注意和数据库格式一致
//不包含的范围查询
QueryBuilder range = QueryBuilders.rangeQuery(field).gt(0).lt(11);
//包含的范围查询
QueryBuilder range = QueryBuilders.rangeQuery(field).from(0).to(11);
3.IN查询
QueryBuilder terms = QueryBuilders.termsQuery("id", idList);
2.多字段匹配单值
MultiMatchQueryBuilder builder = QueryBuilders.multiMatchQuery(value, fields);
3.单(多)字段匹配多值
//构建匹配字段及其优先级
Map<String,Float> map = new HashMap();
 int length = fields.length;
 for (int i = 0; i < length; i++) {
        map.put(fields[i],Float.valueOf(length-i));
 }
//其中value中,eg:“A 神经 FFF” 表示这三个都搜索。
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value).fields(map);
4.查询指定想要的字段(或不想要的字段)
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
                    .setFetchSource(shows, null);//关键方法,前面为想要的字段,后面为不想要的字段
5.排序
SortBuilder sort = SortBuilders.fieldSort(field).order(SortOrder.ASC);
SortBuilders.scoreSort();//得分权重排序
//多个排序可以按照顺序来添加
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
                    .addSort(defaultScoreSort()).addSort(sort);
4.计总数
ValueCountAggregationBuilder aggregation =
                    AggregationBuilders.count("count").field(field);
SearchRequestBuilder sr = esClient.prepareSearch(indexName).addAggregation(aggregation);
if (CollectionUtils.isNotEmpty(conditions))
      sr = sr.setQuery(builderQueries(conditions));
 SearchResponse response = sr.execute().get();
ValueCount count = response.getAggregations().get("count");
return count.getValue();
6.分页

在ES中分页有两种,一种是静态分页(又称游标分页),一种动态分页(又称深度分页)。

具体采用哪种分页,请参考上面DSL部分
动态分页

SearchRequestBuilder srb = esClient.prepareSearch(indexName)
                    .setFrom(from).setSize(pageSize);

静态分页(取自官网):

SearchResponse scrollResp = esClient.prepareSearch(indexName)
                .addSort(sort)
                .setScroll(new TimeValue(60000))//search context存活时间
                .setQuery(builderQueries(conditions))
                .setFrom(from).setSize(pageSize).get(); //max of 100 hits will be returned for each scroll
        //Scroll until no hits are returned
        do {
            for (SearchHit hit : scrollResp.getHits().getHits()) {
                //Handle the hit...
            }

            scrollResp = esClient.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
        }
        while (scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.

5.插入单条
IndexResponse response = this.esClient.prepareIndex(indexName, typeName).setSource(objectMapper.writeValueAsBytes(t), XContentType.JSON).get();
if (responses.status() == RestStatus.OK) return true;
6.批量插入
BulkRequestBuilder bulkRequestBuilder = this.esClient.prepareBulk();

 for (T t : list) {
        IndexRequestBuilder indexRequestBuilder = esClient.prepareIndex(indexName, typeName).setSource(objectMapper.writeValueAsBytes(t), XContentType.JSON);
        bulkRequestBuilder.add(indexRequestBuilder);
 }

BulkResponse responses = bulkRequestBuilder.execute().actionGet();
if (responses.status() == RestStatus.OK) return true;
7.更新(单条)
UpdateResponse response = this.esClient.prepareUpdate(indexName, typeName, esId)
                    .setDoc(objectMapper.writeValueAsBytes(t), XContentType.JSON).get();
if (response.status() == RestStatus.OK) return true;
8.删除
BulkByScrollResponse response = DeleteByQueryAction.INSTANCE
                    .newRequestBuilder(esClient).source(indexName)
                    .filter(builderQueries(conditions)).get();

参考链接:https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.6/index.html

中文分词

参见优化篇——中文分词。

分词包的使用

最近正在破解搜狗的scel文件,loading。。。。。。

相关文章

网友评论

      本文标题:ES-查询搜索篇

      本文链接:https://www.haomeiwen.com/subject/zrciuxtx.html