ES-查詢搜索篇

REST介紹

REST(REpresentational State Transfer),字面意思為“表述性狀態(tài)傳輸”,一種開發(fā)的約定。
REST約定用HTTP的請(qǐng)求頭POST、GET、PUT、DELETE正好對(duì)應(yīng)CRUD(Create、Read、Update、Delete)四種數(shù)據(jù)操作。

索引、映射的建立

索引的建立:

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

{
  "settings": {
    "number_of_shards": 1,//分片數(shù)量
    "number_of_replicas": 0//副本分片數(shù)量
  }
}

映射的建立:

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,來(lái)查看對(duì)應(yīng)的DSL(json格式)。

在ES中進(jìn)行查詢,默認(rèn)的分詞器對(duì)于單個(gè)漢字都會(huì)進(jìn)行分詞,標(biāo)點(diǎn)符號(hào)不計(jì)入分詞,以空格來(lái)間隔英語(yǔ)單詞。對(duì)于not_analyzed不計(jì)入分詞器,只能全部搜索(或者用通配符查詢、前綴查詢)。對(duì)于計(jì)入分詞的,term、match*(match系列)、querystring都支持,而且查詢比較良好。keyword或者數(shù)字類型,都只支持整個(gè)匹配。

說(shuō)一說(shuō)分頁(yè),分頁(yè)都深度分頁(yè)和游標(biāo)分頁(yè)。
深度分頁(yè)是每一次都會(huì)從最新的數(shù)據(jù)中進(jìn)行查詢。適合于實(shí)時(shí)查詢分頁(yè)。因?yàn)樯疃确猪?yè)與CPU、IO、帶寬、內(nèi)存都有關(guān)。所以需要限制深度分頁(yè)的頁(yè)數(shù),防止因?yàn)橐陨显颍ɑ蚺老x)造成卡頓或者宕機(jī)。
游標(biāo)分頁(yè)是在你查詢時(shí),會(huì)初始化一個(gè)快照,在遍歷時(shí),從這個(gè)快照里取數(shù)據(jù),也就是說(shuō),在初始化后對(duì)索引插入、刪除、更新數(shù)據(jù)都不會(huì)影響遍歷結(jié)果。適用于后端對(duì)于數(shù)據(jù)的大批量分析。

2、JAVA篇

以下所有的方法都寫重點(diǎn)部分,需要樣例,請(qǐng)參見(jiàn)GitHub:https://github.com/lingbao08/springboot-example.git。

1. 創(chuàng)建查詢?nèi)萜?/h5>
//此容器可以放置所有的queryBuilder
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
1. 查詢字符串
//精確查詢,查詢有該分詞的文檔
QueryBuilder termQuery = QueryBuilders.termQuery(field, value);
//字符串查詢,查詢包含該分詞的文檔(英文只針對(duì)于單詞,中文可能會(huì)拆開該詞語(yǔ):策略視分詞器而定)
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value)
             .field(field,2f);//可以指定單字段,也可以不指定,不指定按照默認(rèn)字段查詢
//              .fields(map)//多個(gè)字段
2.查詢范圍值
//可以只選大于而不選小于。可以用于查詢?nèi)掌?、?shù)字、字符串等。
//比較日期時(shí)注意和數(shù)據(jù)庫(kù)格式一致
//不包含的范圍查詢
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.單(多)字段匹配多值
//構(gòu)建匹配字段及其優(yōu)先級(jí)
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 神經(jīng) FFF” 表示這三個(gè)都搜索。
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value).fields(map);
4.查詢指定想要的字段(或不想要的字段)
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
                    .setFetchSource(shows, null);//關(guān)鍵方法,前面為想要的字段,后面為不想要的字段
5.排序
SortBuilder sort = SortBuilders.fieldSort(field).order(SortOrder.ASC);
SortBuilders.scoreSort();//得分權(quán)重排序
//多個(gè)排序可以按照順序來(lái)添加
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
                    .addSort(defaultScoreSort()).addSort(sort);
4.計(jì)總數(shù)
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.分頁(yè)

在ES中分頁(yè)有兩種,一種是靜態(tài)分頁(yè)(又稱游標(biāo)分頁(yè)),一種動(dòng)態(tài)分頁(yè)(又稱深度分頁(yè))。

具體采用哪種分頁(yè),請(qǐng)參考上面DSL部分。
動(dòng)態(tài)分頁(yè)

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

靜態(tài)分頁(yè)(取自官網(wǎng)):

SearchResponse scrollResp = esClient.prepareSearch(indexName)
                .addSort(sort)
                .setScroll(new TimeValue(60000))//search context存活時(shí)間
                .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。

中文分詞

參見(jiàn)優(yōu)化篇——中文分詞。

分詞包的使用

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容