23個最有用的ES檢索技巧(Java API實現(xiàn))

前言

本文是對 23個最有用的Elasticseaerch檢索技巧 一文提到的ES檢索技巧進行 Java API 的簡單實現(xiàn)葵礼,但僅限于簡單實現(xiàn)柱告,并不考慮包括參數(shù)校驗苛萎,異常處理洞翩,日志處理焊虏,安全等問題港令,僅供參考

代碼見 UsefullESSearchSkill ,原查詢語句請對照原文

運行環(huán)境

JDK version : 10.0.2
gradle version : 4.7
Elasticsearch version : 6.3.2
IDEA version : 2018.2

運行前請啟動 ES 實例啥容,并修改 application.properties 文件中的ES配置

類介紹

實體類 Book

注意:日期 publish_date 的類型設(shè)置為 String 是避免 Java 到 ES 之間復雜的轉(zhuǎn)換工作,在ES中該字段仍然被識別為 date 類型

public class Book {
    public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private String id;
    private String title;
    private List<String> authors;
    private String summary;
    private String publish_date;
    private Integer num_reviews;
    private String publisher;
    ...
}

公共類 Constants

定義了一些常用的常量

public class Constants {
    // 字段名

    public static String ID = "id";
    public static String TITLE = "title";
    public static String AUTHORS = "authors";
    public static String SUMMARY = "summary";
    public static String PUBLISHDATE = "publish_date";
    public static String PUBLISHER = "publisher";
    public static String NUM_REVIEWS = "num_reviews";

    public static String TITLE_KEYWORD = "title.keyword";
    public static String PUBLISHER_KEYWORD = "publisher.keyword";


    // 過濾要返回的字段

    public static String[] fetchFieldsTSPD = {ID, TITLE, SUMMARY, PUBLISHDATE};
    public static String[] fetchFieldsTA = {ID, TITLE, AUTHORS};
    public static String[] fetchFieldsSA = {ID, SUMMARY, AUTHORS};
    public static String[] fetchFieldsTSA = {ID, TITLE, SUMMARY, AUTHORS};
    public static String[] fetchFieldsTPPD = {ID, TITLE, PUBLISHER, PUBLISHDATE};
    public static String[] fetchFieldsTSPN = {ID, TITLE, SUMMARY, PUBLISHER, NUM_REVIEWS};


    // 高亮

    public static HighlightBuilder highlightS = new HighlightBuilder().field(SUMMARY);
}

公共類 EsConfig

創(chuàng)建 ES 客戶端實例顷霹,ES 客戶端用于與 ES 集群進行交互

@Configuration
public class EsConfig {

    @Value("${elasticsearch.cluster-nodes}")
    private String clusterNodes;

    @Value("${elasticsearch.cluster-name}")
    private String clusterName;

    @Bean
    public Client client() {
        Settings settings = Settings.builder().put("cluster.name", clusterName)
                .put("client.transport.sniff", true).build();

        TransportClient client = new PreBuiltTransportClient(settings);
        try {
            if (clusterNodes != null && !"".equals(clusterNodes)) {
                for (String node : clusterNodes.split(",")) {
                    String[] nodeInfo = node.split(":");
                    client.addTransportAddress(new TransportAddress(InetAddress.getByName(nodeInfo[0]), Integer.parseInt(nodeInfo[1])));
                }
            }
        } catch (UnknownHostException e) {
        }

        return client;
    }
}

數(shù)據(jù)獲取工具類 DataUtil

這里的數(shù)據(jù)也就是 23個最有用的ES檢索技巧 文中用于實驗的4條數(shù)據(jù)

public class DataUtil {

    public static SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 模擬獲取數(shù)據(jù)
     */
    public static List<Book> batchData() {
        List<Book> list = new LinkedList<>();
        Book book1 = new Book("1", "Elasticsearch: The Definitive Guide", Arrays.asList("clinton gormley", "zachary tong"),
                "A distibuted real-time search and analytics engine", "2015-02-07", 20, "oreilly");
        Book book2 = new Book("2", "Taming Text: How to Find, Organize, and Manipulate It", Arrays.asList("grant ingersoll", "thomas morton", "drew farris"),
                "organize text using approaches such as full-text search, proper name recognition, clustering, tagging, information extraction, and summarization",
                "2013-01-24", 12, "manning");
        Book book3 = new Book("3", "Elasticsearch in Action", Arrays.asList("radu gheorge", "matthew lee hinman", "roy russo"),
                "build scalable search applications using Elasticsearch without having to do complex low-level programming or understand advanced data science algorithms",
                "2015-12-03", 18, "manning");
        Book book4 = new Book("4", "Solr in Action", Arrays.asList("trey grainger", "timothy potter"), "Comprehensive guide to implementing a scalable search engine using Apache Solr",
                "2014-04-05", 23, "manning");

        list.add(book1);
        list.add(book2);
        list.add(book3);
        list.add(book4);

        return list;
    }

    public static Date parseDate(String dateStr) {
        try {
            return dateFormater.parse(dateStr);
        } catch (ParseException e) {
        }
        return null;
    }

公共查詢工具類 CommonQueryUtils

對執(zhí)行完ES查詢請求后的數(shù)據(jù)進行解析

public class CommonQueryUtils {

    public static Gson gson = new GsonBuilder().setDateFormat("YYYY-MM-dd").create();

    /**
     * 處理ES返回的數(shù)據(jù)咪惠,封裝
     */
    public static List<Book> parseResponse(SearchResponse searchResponse) {
        List<Book> list = new LinkedList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {
            // 用gson直接解析
            Book book = gson.fromJson(hit.getSourceAsString(), Book.class);
            
            list.add(book);
        }
        return list;
    }

    /**
     * 解析完數(shù)據(jù)后,構(gòu)建 Response 對象
     */
    public static Response<List<Book>> buildResponse(SearchResponse searchResponse) {
        // 超時處理
        if (searchResponse.isTimedOut()) {
            return new Response<>(ResponseCode.ESTIMEOUT);
        }
        // 處理ES返回的數(shù)據(jù)
        List<Book> list = parseResponse(searchResponse);
        // 有shard執(zhí)行失敗
        if (searchResponse.getFailedShards() > 0) {
            return new Response<>(ResponseCode.FAILEDSHARDS, list);
        }
        return new Response<>(ResponseCode.OK, list);
    }
    ...
}

數(shù)據(jù)準備

BulkTests

創(chuàng)建索引泼返,以及使用 bulk API 批量插入數(shù)據(jù)

@RunWith(SpringRunner.class)
@SpringBootTest
public class BulkTests {

    // 在Test中 Autowired需要引入包 org.elasticsearch.plugin:transport-netty4-client:6.3.2硝逢,否則異常找不到Transport類
    @Autowired
    private Client client;

    @Value("${elasticsearch.bookIndex}")
    private String bookIndex;

    @Value("${elasticsearch.bookType}")
    private String bookType;

    private Gson gson = new GsonBuilder().setDateFormat("YYYY-MM-dd").create();

    /**
     * 創(chuàng)建索引,設(shè)置 settings绅喉,設(shè)置mappings
     */
    @Test
    public void createIndex() {
        int settingShards = 1;
        int settingReplicas = 0;

        // 判斷索引是否存在渠鸽,存在則刪除
        IndicesExistsResponse indicesExistsResponse = client.admin().indices().prepareExists(bookIndex).get();

        if (indicesExistsResponse.isExists()) {
            System.out.println("索引 " + bookIndex + " 存在!");
            // 刪除索引柴罐,防止報異常  ResourceAlreadyExistsException[index [bookdb_index/yL05ZfXFQ4GjgOEM5x8tFQ] already exists
            DeleteIndexResponse deleteResponse = client.admin().indices().prepareDelete(bookIndex).get();
            if (deleteResponse.isAcknowledged()){
                System.out.println("索引" + bookIndex + "已刪除");
            }else {
                System.out.println("索引" + bookIndex + "刪除失敗");
            }


        } else {
            System.out.println("索引 " + bookIndex + " 不存在徽缚!");
        }

        // 設(shè)置Settings
        CreateIndexResponse response = client.admin().indices().prepareCreate(bookIndex)
                .setSettings(Settings.builder()
                        .put("index.number_of_shards", settingShards)
                        .put("index.number_of_replicas", settingReplicas))
                .get();

        // 查看結(jié)果
        GetSettingsResponse getSettingsResponse = client.admin().indices()
                .prepareGetSettings(bookIndex).get();
        System.out.println("索引設(shè)置結(jié)果");
        for (ObjectObjectCursor<String, Settings> cursor : getSettingsResponse.getIndexToSettings()) {
            String index = cursor.key;
            Settings settings = cursor.value;
            Integer shards = settings.getAsInt("index.number_of_shards", null);
            Integer replicas = settings.getAsInt("index.number_of_replicas", null);
            System.out.println("index:" + index + ", shards:" + shards + ", replicas:" + replicas);

            Assert.assertEquals(java.util.Optional.of(settingShards), java.util.Optional.of(shards));
            Assert.assertEquals(java.util.Optional.of(settingReplicas), java.util.Optional.of(replicas));
        }
    }

    /**
     * Bulk 批量插入數(shù)據(jù)
     */
    @Test
    public void bulk() {
        List<Book> list = DateUtil.batchData();

        BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();

        // 添加index操作到 bulk 中
        list.forEach(book -> {
            // 新版的API中使用setSource時,參數(shù)的個數(shù)必須是偶數(shù)革屠,否則需要加上 setSource(json, XContentType.JSON)
            bulkRequestBuilder.add(client.prepareIndex(bookIndex, bookType, book.getId()).setSource(gson.toJson(book), XContentType.JSON));
        });

        BulkResponse responses = bulkRequestBuilder.get();
        if (responses.hasFailures()) {
            // bulk有失敗
            for (BulkItemResponse res : responses) {
                System.out.println(res.getFailure());
            }
            Assert.assertTrue(false);
        }
    }
}

開始查詢

控制類

查詢接口

@RestController
@RequestMapping("basicmatch")
public class BasicMatchQueryController {

    @Autowired
    private BasicMatchQueryService basicMatchQueryService;

    /**
     * 1.1 對 "guide" 執(zhí)行全文檢索
     * 測試:http://localhost:8080/basicmatch/multimatch?query=guide
     */
    @RequestMapping("multimatch")
    public Response<List<Book>> multiMatch(@RequestParam(value = "query", required = true) String query) {
        return basicMatchQueryService.multiBatch(query);
    }

    /**
     * 1.2 指定特定字段檢索
     * 測試:http://localhost:8080/basicmatch/match?title=in action&from=0&size=4
     */
    @RequestMapping("match")
    public ResponsePage<List<Book>> match(MatchForm form) {
        return basicMatchQueryService.match(form);
    }

    /**
     * 2 對 "guide" 執(zhí)行多字段檢索
     * 測試:http://localhost:8080/basicmatch/multifield?query=guide
     */
    @RequestMapping("multifield")
    public Response<List<Book>> multiField(@RequestParam(value = "query", required = true) String query) {
        return basicMatchQueryService.multiField(query);
    }

    /**
     * 3凿试、 Boosting提升某字段得分的檢索( Boosting): 將“摘要”字段的得分提高了3倍
     * 測試:http://localhost:8080/basicmatch/multifieldboost?query=elasticsearch guide
     */
    @RequestMapping("multifieldboost")
    public Response<List<Book>> multiFieldboost(@RequestParam(value = "query", required = true) String query) {
        return basicMatchQueryService.multiFieldboost(query);
    }

    /**
     * 4、Bool檢索( Bool Query)
     * 測試:http://localhost:8080/basicmatch/bool?shouldTitles=Elasticsearch&shouldTitles=Solr&mustAuthors=clinton gormely&mustNotAuthors=radu gheorge
     */
    @RequestMapping("bool")
    public Response<List<Book>> bool(@ModelAttribute BoolForm form) {
        return basicMatchQueryService.bool(form);
    }

    /**
     * 5似芝、 Fuzzy 模糊檢索( Fuzzy Queries)
     */
    @RequestMapping("fuzzy")
    public Response<List<Book>> fuzzy(String query) {
        return basicMatchQueryService.fuzzy(query);
    }

    /**
     * 6那婉、 Wildcard Query 通配符檢索
     * 測試:http://localhost:8080/basicmatch/wildcard?pattern=t*
     */
    @RequestMapping("wildcard")
    public Response<List<Book>> wildcard(String pattern) {
        return basicMatchQueryService.wildcard(Constants.AUTHORS, pattern);
    }


    /**
     * 7、正則表達式檢索( Regexp Query)
     * 測試:http://localhost:8080/basicmatch/regexp
     */
    @RequestMapping("regexp")
    public Response<List<Book>> regexp(String regexp) {
        // 由于Tomcat的原因党瓮,直接接收有特殊字符的 正則表達式 會異常详炬,所以這里寫死,不過多探究
        // 若
        regexp = "t[a-z]*y";
        return basicMatchQueryService.regexp(Constants.AUTHORS, regexp);
    }

    /**
     * 8寞奸、匹配短語檢索( Match Phrase Query)
     * 測試:http://localhost:8080/basicmatch/phrase?query=search engine
     */
    @RequestMapping("phrase")
    public Response<List<Book>> phrase(String query) {
        return basicMatchQueryService.phrase(query);
    }

    /**
     * 9呛谜、匹配詞組前綴檢索
     * 測試:http://localhost:8080/basicmatch/phraseprefix?query=search en
     */
    @RequestMapping("phraseprefix")
    public Response<List<Book>> phrasePrefix(String query) {
        return basicMatchQueryService.phrasePrefix(query);
    }

    /**
     * 10、字符串檢索( Query String)
     * 測試:http://localhost:8080/basicmatch/querystring?query=(saerch~1 algorithm~1) AND (grant ingersoll)  OR (tom morton)
     */
    @RequestMapping("querystring")
    public Response<List<Book>> queryString(String query) {
        return basicMatchQueryService.queryString(query);
    }

    /**
     * 11枪萄、簡化的字符串檢索 (Simple Query String)
     * 測試:http://localhost:8080/basicmatch/simplequerystring?query=(saerch~1 algorithm~1) AND (grant ingersoll)  OR (tom morton)
     */
    @RequestMapping("simplequerystring")
    public Response<List<Book>> simplequerystring(String query) {
        // 這里寫死隐岛,僅為測試
        query = "(saerch~1 algorithm~1) + (grant ingersoll)  | (tom morton)";
        return basicMatchQueryService.simpleQueryString(query);
    }

    /**
     * 12、Term=檢索(指定字段檢索)
     * 測試:http://localhost:8080/basicmatch/term?query=manning
     */
    @RequestMapping("term")
    public Response<List<Book>> term(String query) {
        return basicMatchQueryService.term(query);
    }

    /**
     * 13瓷翻、Term排序檢索-(Term Query - Sorted)
     * 測試:http://localhost:8080/basicmatch/termsort?query=manning
     */
    @RequestMapping("termsort")
    public Response<List<Book>> termsort(String query) {
        return basicMatchQueryService.termsort(query);
    }

    /**
     * 14聚凹、范圍檢索(Range query)
     * 測試:http://localhost:8080/basicmatch/range?startDate=2015-01-01&endDate=2015-12-31
     */
    @RequestMapping("range")
    public Response<List<Book>> range(String startDate, String endDate) {
        return basicMatchQueryService.range(startDate, endDate);
    }

    /**
     * 15. 過濾檢索
     * 測試:http://localhost:8080/basicmatch/filter?query=elasticsearch&gte=20
     */
    @RequestMapping("filter")
    public Response<List<Book>> filter(String query, Integer gte, Integer lte) {
        return basicMatchQueryService.filter(query, gte, lte);
    }

    /**
     * 17割坠、 Function 得分:Field值因子( Function Score: Field Value Factor)
     * 測試:http://localhost:8080/basicmatch/fieldvaluefactor?query=search engine
     */
    @RequestMapping("fieldvaluefactor")
    public Response<List<Book>> fieldValueFactor(String query) {
        return basicMatchQueryService.fieldValueFactor(query);
    }

    /**
     * 18、 Function 得分:衰減函數(shù)( Function Score: Decay Functions )
     * 測試:http://localhost:8080/basicmatch/decay?query=search engines&origin=2014-06-15
     */
    @RequestMapping("decay")
    public Response<List<Book>> decay(String query, @RequestParam(value = "origin", defaultValue = "2014-06-15") String origin) {
        return basicMatchQueryService.decay(query, origin);
    }

    /**
     * 19妒牙、Function得分:腳本得分( Function Score: Script Scoring )
     * 測試:ES需要配置允許groovy腳本運行才可以
     */
    @RequestMapping("script")
    public Response<List<Book>> script(String query, @RequestParam(value = "threshold", defaultValue = "2015-07-30") String threshold) {
        return basicMatchQueryService.script(query, threshold);
    }
}

服務(wù)類

@Service
public class BasicMatchQueryService {
    @Autowired
    private Client client;

    @Value("${elasticsearch.bookIndex}")
    private String bookIndex;

    @Value("${elasticsearch.bookType}")
    private String bookType;

    /**
     * 進行ES查詢韭脊,執(zhí)行請求前后打印出 查詢語句 和 查詢結(jié)果
     */
    private SearchResponse requestGet(String queryName, SearchRequestBuilder requestBuilder) {
        System.out.println(queryName + " 構(gòu)建的查詢:" + requestBuilder.toString());
        SearchResponse searchResponse = requestBuilder.get();
        System.out.println(queryName + " 搜索結(jié)果:" + searchResponse.toString());
        return searchResponse;
    }
    ...
}

1.1 對 "guide" 執(zhí)行全文檢索 Multi Match Query

    public Response<List<Book>> multiBatch(String query) {
        MultiMatchQueryBuilder queryBuilder = new MultiMatchQueryBuilder(query);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setTypes(bookType).setQuery(queryBuilder);

        SearchResponse searchResponse = requestGet("multiBatch", requestBuilder);

        return CommonQueryUtils.buildResponse(searchResponse);
    }

1.2 在標題字段(title)中搜索帶有 "in action" 字樣的圖書

    public ResponsePage<List<Book>> match(MatchForm form) {
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", form.getTitle());
        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("title").fragmentSize(200);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setTypes(bookType).setQuery(matchQueryBuilder)
                .setFrom(form.getFrom()).setSize(form.getSize())
                .highlighter(highlightBuilder)
                // 設(shè)置 _source 要返回的字段
                .setFetchSource(Constants.fetchFieldsTSPD, null);
        ...
    }

多字段檢索 (Multi-field Search)

    public Response<List<Book>> multiField(String query) {
        MultiMatchQueryBuilder queryBuilder = new MultiMatchQueryBuilder(query).field("title").field("summary");

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setTypes(bookType).setQuery(queryBuilder);
        ...
    }

3、 Boosting提升某字段得分的檢索( Boosting),將“摘要”字段的得分提高了3倍

    public Response<List<Book>> multiFieldboost(String query) {
        MultiMatchQueryBuilder queryBuilder = new MultiMatchQueryBuilder(query).field("title").field("summary", 3);
        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setTypes(bookType).setQuery(queryBuilder);
        ...
    }

4单旁、Bool檢索( Bool Query)

    /**
     * 在標題中搜索一本名為 "Elasticsearch" 或 "Solr" 的書,
     * AND由 "clinton gormley" 創(chuàng)作饥伊,但NOT由 "radu gheorge" 創(chuàng)作
     */
    public Response<List<Book>> bool(BoolForm form) {
        BoolQueryBuilder boolQuery = new BoolQueryBuilder();
        // 搜索標題 should
        BoolQueryBuilder shouldTitleBool = new BoolQueryBuilder();
        form.getShouldTitles().forEach(title -> {
            shouldTitleBool.should().add(new MatchQueryBuilder("title", title));
        });
        boolQuery.must().add(shouldTitleBool);
        // match 作者
        form.getMustAuthors().forEach(author -> {
            boolQuery.must().add(new MatchQueryBuilder("authors", author));
        });
        // not match 作者
        form.getMustNotAuthors().forEach(author -> {
            boolQuery.mustNot().add(new MatchQueryBuilder("authors", author));
        });
        ...
    }

5象浑、 Fuzzy 模糊檢索( Fuzzy Queries)

    public Response<List<Book>> fuzzy(String query) {
        MultiMatchQueryBuilder queryBuilder = new MultiMatchQueryBuilder(query)
                .field("title").field("summary")
                .fuzziness(Fuzziness.AUTO);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setTypes(bookType).setQuery(queryBuilder)
                .setFetchSource(Constants.fetchFieldsTSPD, null)
                .setSize(2);
        ...
    }

6、 Wildcard Query 通配符檢索

    /**
     * 要查找具有以 "t" 字母開頭的作者的所有記錄
     */
    public Response<List<Book>> wildcard(String fieldName, String pattern) {
        WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(fieldName, pattern);
        HighlightBuilder highlightBuilder = new HighlightBuilder().field(Constants.AUTHORS, 200);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setTypes(bookType).setQuery(wildcardQueryBuilder)
                .setFetchSource(Constants.fetchFieldsTA, null)
                .highlighter(highlightBuilder);
    }

7琅豆、正則表達式檢索( Regexp Query)

    public Response<List<Book>> regexp(String fieldName, String regexp) {
        RegexpQueryBuilder queryBuilder = new RegexpQueryBuilder(fieldName, regexp);
        HighlightBuilder highlightBuilder = new HighlightBuilder().field(Constants.AUTHORS);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex)
                .setQuery(queryBuilder).setTypes(bookType).highlighter(highlightBuilder)
                .setFetchSource(Constants.fetchFieldsTA, null);
    }

8愉豺、匹配短語檢索( Match Phrase Query)

    public Response<List<Book>> phrase(String query) {
        MultiMatchQueryBuilder queryBuilder = new MultiMatchQueryBuilder(query)
                .field(Constants.TITLE).field(Constants.SUMMARY)
                .type(MultiMatchQueryBuilder.Type.PHRASE).slop(3);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder)
                .setFetchSource(Constants.fetchFieldsTSPD, null);
    }

9、匹配詞組前綴檢索

    public Response<List<Book>> phrasePrefix(String query) {
        MatchPhrasePrefixQueryBuilder queryBuilder = new MatchPhrasePrefixQueryBuilder(Constants.SUMMARY, query)
                .slop(3).maxExpansions(10);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSPD, null);
    }

10茫因、字符串檢索( Query String)

    public Response<List<Book>> queryString(String query) {
        QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder(query);
        queryBuilder.field(Constants.SUMMARY, 2).field(Constants.TITLE)
                .field(Constants.AUTHORS).field(Constants.PUBLISHER);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSA, null);
    }

11蚪拦、簡化的字符串檢索 (Simple Query String)

    public Response<List<Book>> simpleQueryString(String query) {
        SimpleQueryStringBuilder queryBuilder = new SimpleQueryStringBuilder(query);
        queryBuilder.field(Constants.SUMMARY, 2).field(Constants.TITLE)
                .field(Constants.AUTHORS).field(Constants.PUBLISHER);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSA, null)
                .highlighter(Constants.highlightS);
    }

12、Term/Terms檢索(指定字段檢索)

    public Response<List<Book>> term(String query) {
        TermQueryBuilder termQueryBuilder = new TermQueryBuilder(Constants.PUBLISHER, query);

        // terms 查詢
        /*String[] values = {"manning", "oreilly"};
        TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder(Constants.PUBLISHER, values);*/

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(termQueryBuilder)
                .setFetchSource(Constants.fetchFieldsTPPD, null);
    }

13冻押、Term排序檢索-(Term Query - Sorted)

    public Response<List<Book>> termsort(String query) {
        TermQueryBuilder termQueryBuilder = new TermQueryBuilder(Constants.PUBLISHER, query);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(termQueryBuilder)
                .addSort(Constants.PUBLISHER_KEYWORD, SortOrder.DESC)
                .addSort(Constants.TITLE_KEYWORD, SortOrder.ASC)
                .setFetchSource(Constants.fetchFieldsTPPD, null);
    }

14驰贷、范圍檢索(Range query)

    public Response<List<Book>> range(String startDate, String endDate) {
        RangeQueryBuilder queryBuilder = new RangeQueryBuilder(Constants.PUBLISHDATE)
                .gte(startDate).lte(endDate);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder)
                .setFetchSource(Constants.fetchFieldsTPPD, null);
    }

15. 過濾檢索

    public Response<List<Book>> filter(String query, Integer gte, Integer lte) {
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must().add(new MultiMatchQueryBuilder(query).field(Constants.TITLE).field(Constants.SUMMARY));
        if (gte != null || lte != null) {
            RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder(Constants.NUM_REVIEWS);
            if (gte != null) {
                rangeQueryBuilder.gte(gte);
            }
            if (lte != null) {
                rangeQueryBuilder.lte(lte);
            }
            queryBuilder.filter().add(rangeQueryBuilder);
        }

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSPN, null);
    }

17、 Function 得分:Field值因子( Function Score: Field Value Factor)

    public Response<List<Book>> fieldValueFactor(String query) {
        // query
        MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder(query)
                .field(Constants.TITLE).field(Constants.SUMMARY);
        // fieldValueFactor
        FieldValueFactorFunctionBuilder fieldValueFactor = ScoreFunctionBuilders.fieldValueFactorFunction(Constants.NUM_REVIEWS)
                .factor(2).modifier(FieldValueFactorFunction.Modifier.LOG1P);
        // functionscore
        FunctionScoreQueryBuilder queryBuilder = QueryBuilders.functionScoreQuery(multiMatchQueryBuilder, fieldValueFactor);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSPN, null);
    }

18洛巢、 Function 得分:衰減函數(shù)( Function Score: Decay Functions )

    public Response<List<Book>> decay(String query, String origin) {
        MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder(query)
                .field(Constants.TITLE).field(Constants.SUMMARY);
        ExponentialDecayFunctionBuilder exp = ScoreFunctionBuilders.exponentialDecayFunction(Constants.PUBLISHDATE, origin, "30d", "7d");

        FunctionScoreQueryBuilder queryBuilder = QueryBuilders.functionScoreQuery(multiMatchQueryBuilder, exp).boostMode(CombineFunction.REPLACE);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSPN, null);
    }

19括袒、Function得分:腳本得分( Function Score: Script Scoring )

    public Response<List<Book>> script(String query, String threshold) {
        MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder(query)
                .field(Constants.TITLE).field(Constants.SUMMARY);
        // 參數(shù)
        Map<String, Object> params = new HashMap<>();
        params.put("threshold", threshold);
        // 腳本
        String scriptStr = "publish_date = doc['publish_date'].value; num_reviews = doc['num_reviews'].value; if (publish_date > Date.parse('yyyy-MM-dd', threshold).getTime()) { return log(2.5 + num_reviews) }; return log(1 + num_reviews);";
        Script script = new Script(ScriptType.INLINE, "painless", scriptStr, params);

        ScriptScoreFunctionBuilder scriptScoreFunctionBuilder = ScoreFunctionBuilders.scriptFunction(script);

        FunctionScoreQueryBuilder queryBuilder = QueryBuilders.functionScoreQuery(multiMatchQueryBuilder, scriptScoreFunctionBuilder);

        SearchRequestBuilder requestBuilder = client.prepareSearch(bookIndex).setTypes(bookType)
                .setQuery(queryBuilder).setFetchSource(Constants.fetchFieldsTSPN, null);
    }

更多內(nèi)容請訪問我的個人博客:http://laijianfeng.org

打開微信搜索,關(guān)注【小旋鋒】微信公眾號稿茉,及時接收博文推送

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锹锰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子漓库,更是在濱河造成了極大的恐慌恃慧,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渺蒿,死亡現(xiàn)場離奇詭異痢士,居然都是意外死亡,警方通過查閱死者的電腦和手機蘸嘶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門良瞧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人训唱,你說我怎么就攤上這事褥蚯。” “怎么了况增?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵赞庶,是天一觀的道長。 經(jīng)常有香客問我,道長歧强,這世上最難降的妖魔是什么澜薄? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮摊册,結(jié)果婚禮上肤京,老公的妹妹穿的比我還像新娘。我一直安慰自己茅特,他們只是感情好忘分,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著白修,像睡著了一般妒峦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兵睛,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天肯骇,我揣著相機與錄音,去河邊找鬼祖很。 笑死笛丙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的假颇。 我是一名探鬼主播若债,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拆融!你這毒婦竟也來了蠢琳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤镜豹,失蹤者是張志新(化名)和其女友劉穎傲须,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趟脂,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡泰讽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了昔期。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片已卸。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖硼一,靈堂內(nèi)的尸體忽然破棺而出累澡,到底是詐尸還是另有隱情,我是刑警寧澤般贼,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布愧哟,位于F島的核電站奥吩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蕊梧。R本人自食惡果不足惜霞赫,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肥矢。 院中可真熱鬧端衰,春花似錦、人聲如沸甘改。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽楼誓。三九已至,卻和暖如春名挥,著一層夾襖步出監(jiān)牢的瞬間疟羹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工禀倔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留榄融,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓救湖,卻偏偏與公主長得像愧杯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鞋既,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容