弾性検索するJava API(文書操作API、クエリDSLクエリAPI)は、検索エンジンの戦闘デモをES


弾性検索本当の小さなデモ:https://github.com/simonsfan/springboot-quartz-demo、支店:feature_es


前のAPI検索(クエリDSL)の弾性検索インデックスとドキュメントのAPIのelasticsearch記事は次のような共通のネイティブAPIのあまり弾性検索(以下、ES)を言及し、Benpianは使用を組み合わせる方法について話し始めたAPIのJava開発指数をES CRUDと複雑なクエリ。私は、あなたがMavenのは、最初に頼る必要性を導入するのは簡単テストにspringbootにここでは例を使用します。

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>5.6.1</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.7</version>
</dependency>

springbootプロファイルapplication.ymlは9300には、Javaと対話するポートESであることを、以下の構成、ノートを追加した、HTTPポート番号9200と相互作用しないES:

elasticsearch:
  cluster:
    name: elasticsearch
  host: 127.0.0.1
  port: 9300

Movie_index指数は、2つの新しいテスト・データを確立し、テストするために使用しました:

PUT /movie_index
{
  "mappings": {
    "info": {
      "properties": {
        "actors": {
          "type": "text"
        },
        "alias": {
          "type": "text"
        },
        "directors": {
          "type": "text"
        },
        "introduction": {
          "type": "text"
        },
        "label": {
          "type": "text"
        },
        "name": {
          "type": "text"
        },
        "score": {
          "type": "float"
        },
        "release": {
          "type": "date"
        },
        "area": {
          "type": "keyword"
        }
      }
    }
  }
}

POST /movie_index/info
{
  "name": "毒液",
  "alias": "毒液",
  "actors": "汤姆·哈迪 米歇尔·威廉姆斯 伍迪·哈里森 里兹·阿迈德 珍妮·斯蕾特",
  "directors": "鲁本·弗雷斯彻",
  "score": 9,
  "area": "美国",
  "label": "2018年 美国 电影 动作 好莱坞 VIP电影 VIP尊享 动作 新片",
  "release": "2019",
  "introduction": "017年3月17日,索尼宣布将为蜘蛛侠的死对头“毒液”(Venom)打造外传电影,并计划于2018年10月5日上映。《毒液》被视作蜘蛛侠系列的外传,将由《超凡蜘蛛侠2》的编剧艾里克斯·库兹曼(《木乃伊》)执导,《蜘蛛侠:英雄归来》的制片人马修·托马齐以及漫威影业前CEO阿维·阿拉德担任制片,由丹特·哈珀(《明日边缘》)编剧。他们表示,此片与汤姆·赫兰德主演的蜘蛛侠三部曲没什么关系,是一个独立的外传。关于此片的更多细节并未透露。   2017年3月28日,索尼确认《毒液》将以R级的形式进行开发。   2017年5月,确认英国演员汤姆·哈迪将出演漫威蜘蛛侠衍生片《毒液》,将扮演自由摄影师Eddie Brock 。   2017年6月,制片人艾米·帕斯卡尔证实影片将和漫威电影宇宙连接,作为附属电影,并且有机会让汤姆·赫兰德回归饰演蜘蛛侠。"
}

POST /movie_index/info
{
  "name": "我不是药神",
  "alias": "我不是药神",
  "actors": "徐峥 王传君 周一围 谭卓 章宇",
  "directors": "文牧野",
  "score": 9.2,
  "area": "内地",
  "label": "国内院线 VIP电影 剧情 VIP尊享 院线 喜剧 喜剧 新片 剧情",
  "release": "2018",
  "introduction": "普通中年男子程勇(徐峥 饰)经营着一家保健品店,失意又失婚。不速之客吕受益(王传君 饰)的到来,让他开辟了一条去印度买药做“代购”的新事业,虽然困难重重,但他在这条“买药之路”上发现了商机,一发不可收拾地做起了治疗慢粒白血病的印度仿制药独家代理商。赚钱的同时,他也认识了几个病患及家属,为救女儿被迫做舞女的思慧(谭卓 饰)、说一口流利“神父腔”英语的刘牧师(杨新鸣 饰),以及脾气暴烈的“黄毛”(章宇 饰),几个人合伙做起了生意,利润倍增的同时也危机四伏。程勇昔日的小舅子曹警官(周一围 饰)奉命调查仿制药的源头,假药贩子张长林(王砚辉 饰)和瑞士正牌医药代表(李乃文 饰)也对其虎视眈眈,生意逐渐变成了一场关于救赎的拉锯战。"
}

お客様が第一弾性、検索終了のtransportClient注入しました:

@Configuration
public class ElasticSearchConfig {

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

    @Value("${elasticsearch.port}")
    private int esPort;

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

    @Bean
    public TransportClient esClient() throws UnknownHostException {
        TransportClient client = null;
        try {
            Settings settings = Settings.builder()
                    .put("client.transport.sniff", true)
                    .put("cluster.name", this.esName)
                    .build();

            InetSocketTransportAddress master = new InetSocketTransportAddress(InetAddress.getByName(esHost), esPort);

            client = new PreBuiltTransportClient(settings).addTransportAddress(master);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return client;
    }
}

顧客に直接注入端@AutowiredのtransportClient以降の必要性をES。


図書 ドキュメントAPIS

などを変更して再検索文書、バッチ操作、主に反映追加と削除

インデックスのAPI

新しいドキュメントのインデックスAPIのパフォーマンス(インデックスが新しい指示しますが存在しない場合)、あなたはインデックスパラメータ名、タイプ、三つのパラメータのJSONデータを指定し、状態が戻りIndexResponse新しい成功に応じているかどうかそれから決定する必要があります。

    @Autowired
    private TransportClient transportClient;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 新增文档
     *
     * @param indexTemplate
     * @return
     */
    @Override
    public String addIndex(MovieIndexTemplate indexTemplate) {
        if (indexTemplate == null) {
            return ResultUtil.fail();
        }
        try {
            IndexRequestBuilder indexRequestBuilder = transportClient.prepareIndex(INDEX, TYPE).setSource(objectMapper.writeValueAsBytes(indexTemplate), XContentType.JSON);
            IndexResponse indexResponse = indexRequestBuilder.get();
            if (indexResponse.status() == RestStatus.CREATED) {
                logger.info("name={},新增文档成功", indexTemplate.getName());
                return ResultUtil.success();
            }
        } catch (JsonProcessingException e) {
            logger.error("");
        }
        return ResultUtil.fail();
    }
    @Autowired
    private MovieSearchService movieSearchService;

    @Test
    public void testAddDocument() {
        MovieIndexTemplate indexTemplate = new MovieIndexTemplate();
        indexTemplate.setName("喜剧之王");
        indexTemplate.setAlias("喜剧之王");
        indexTemplate.setActors("周星驰,莫文蔚,张柏芝,吴孟达,林子善,田启文");
        indexTemplate.setDirectors("周星驰  李力持");
        indexTemplate.setIntroduction("《喜剧之王》是星辉海外有限公司出品的一部喜剧电影,由李力持、周星驰执导,周星驰、 莫文蔚、张柏芝等主演。该片于1999年2月13日在香港上映。影片讲述对喜剧情有独钟的尹天仇与舞女柳飘飘逐渐产生感情,之后在杜娟儿的帮助下,尹天仇终于获得机会演主角,但又陷入与柳飘飘、杜娟儿的三角恋漩涡之中");
        indexTemplate.setArea("内地");
        indexTemplate.setScore(9.4f);
        indexTemplate.setLabel("喜剧 爱情");
        indexTemplate.setRelease("1999");
        movieSearchService.addIndex(indexTemplate);
    }

APIを取得

特定のデータ取得のためのAPIドキュメントを取得し、インデックス名、タイプ、ID 3つのパラメータを受け取ります:

    @Override
    public String getIndex(String id) {
        GetResponse getResponse = transportClient.prepareGet(INDEX, TYPE, id).get();
        String result = getResponse.getSourceAsString();
        logger.info("get api result ={},", result);
        if (StringUtils.isEmpty(result)) {
            return ResultUtil.fail();
        }
        return ResultUtil.success(result);
    }
    @Test
    public void getIndex(){
        String id = "hTCYWmgBBHn7EfncQOq6";
        movieSearchService.getIndex(id);
    }

唯一の1つのID APIがサポートを取得していますが、使用することができ、マルチGET APIをに対応する1つのIDよりも多くのワンタイムパスに戻る複数の結果セット:

    //multi getindex
    public void getIndex2(String[] keyword) {
        MultiGetResponse multiGetItemResponse = transportClient.prepareMultiGet()
                .add(INDEX, TYPE, keyword[0])
                .add(INDEX, TYPE, keyword[1])
                .get();
        for (MultiGetItemResponse getItemResponse : multiGetItemResponse) {
            GetResponse response = getItemResponse.getResponse();
            String json = response.getSourceAsString();
        }
    }

削除API

削除APIは同じGET APIに類似した指定された文書データを、削除するために使用され、また、インデックス名、タイプ、ID 3つのパラメータを受け取ります:

    @Override
    public String deleteIndex(String id) {
        DeleteRequestBuilder deleteRequestBuilder = transportClient.prepareDelete(INDEX, TYPE, id);
        DeleteResponse deleteResponse = deleteRequestBuilder.get();
        if (deleteResponse.status() == RestStatus.OK) {
            logger.info("");
            return ResultUtil.success();
        }
        return ResultUtil.fail();
    }
    @Test
    public void deleteIndex(){
        String id = "hTCYWmgBBHn7EfncQOq6";
        movieSearchService.deleteIndex(id);
    }

ことで、クエリのAPIを削除します。

この削除操作は、条件指定されたデータに応じてフィルタを取り除くために、削除されたよりもIDに簡単かつ柔軟記載の数は、例えば、次の一致を映画に基づいて名前フィールドを削除します。

    @Override
    public String deleteByQueryAction(String keyword) {
        BulkByScrollResponse bulkByScrollResponse = DeleteByQueryAction.INSTANCE.newRequestBuilder(transportClient).filter(QueryBuilders.matchQuery(MovieSearch.NAME, keyword)).source(INDEX).get();
        long deleted = bulkByScrollResponse.getDeleted();
        logger.info("根据条件keyword={}删除result={}", keyword, deleted);
        if (deleted < 1) {
            logger.info("根据条件keyword={}删除失败", keyword);
            return ResultUtil.fail();
        }
        logger.info("根据条件keyword={}删除成功", keyword);
        return ResultUtil.success();
    }
    @Test
    public void deleteByQueryAction(){
        String name = "喜剧之王";
        movieSearchService.deleteByQueryAction(name);
    }

このアクションは、ユーザーが設定できるように、非同期直接取得するのではなく、実行され、リスナーの内部における成功と失敗の具体的なロジックに対処するために、クエリ操作で削除このリスナーを設定し、長い時間のために、クエリの実行により削除することがありますので、:

    //异步执行delete by query
    public void deleteByQueryAction1(String keyword) {
        DeleteByQueryAction.INSTANCE.newRequestBuilder(transportClient).filter(QueryBuilders.matchQuery(MovieSearch.NAME, keyword)).source(INDEX).execute(new ActionListener<BulkByScrollResponse>() {
            @Override
            public void onResponse(BulkByScrollResponse bulkByScrollResponse) {
                long deleted = bulkByScrollResponse.getDeleted();
                logger.info("根据条件keyword={}删除result={}", keyword, deleted);
                if (deleted < 1) {
                    logger.info("根据条件keyword={}删除失败", keyword);
                }
                logger.info("根据条件keyword={}删除成功", keyword);
            }

            @Override
            public void onFailure(Exception e) {
                // Hanlder the exception……
            }
        });
    }

バルクAPI

バルクAPIは、削除された、新しい機能が含まれている要求としてバッチ操作をサポートしています。

    //批量bulk操作
    @Override
    public void buldOption(MovieIndexTemplate indexTemplate, String id) throws JsonProcessingException {
        BulkRequestBuilder bulkRequestBuilder = transportClient.prepareBulk();

        bulkRequestBuilder.add(transportClient.prepareDelete(INDEX, TYPE, id));

        bulkRequestBuilder.add(transportClient.prepareIndex(INDEX, TYPE).setSource(objectMapper.writeValueAsBytes(indexTemplate), XContentType.JSON));

        BulkResponse bulkItemResponses = bulkRequestBuilder.get();
        RestStatus status = bulkItemResponses.status();
        logger.info("bulk option result status={}", status);
    }

更新APIと再インデックスAPIはあまりないとインデックスにおける弾性検索が変更を行うことをお勧めではなく、削除されていないため、非常に少ないと、ここで話をして、直接的な方法を追加、更新および再インデックスAPIそうはありません。


図書 クエリDSLのJava API

弾性検索の検索API(クエリDSL)、フィールドタイプのクエリ、複雑なクエリは、  紙がクエリや複雑な問い合わせなどの分野に分け、ESネイティブクエリDSLのAPIを述べ、フィールドのクラス・クエリは、単語クラスのクエリとフルテキストに分けることができます試合。

図書 全試合:試合、match_phrase、QUERY_STRING、simple_query_stringおよびその他のクエリが含まれます。

//Match Query
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(MovieSearch.NAME, "毒液");

//Muitl Match Query
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("", MovieSearch.NAME, MovieSearch.AREA, MovieSearch.INTRODUCTION, MovieSearch.ACTORS, MovieSearch.DIRECTORS);

//Common Terms Query
CommonTermsQueryBuilder commonTermsQueryBuilder = QueryBuilders.commonTermsQuery(MovieSearch.NAME, "毒液");

//Query String Query
QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("毒液").field(MovieSearch.NAME).defaultOperator(Operator.OR);

//Simple Query String Query
SimpleQueryStringBuilder simpleQueryStringBuilder = QueryBuilders.simpleQueryStringQuery("毒液").field(MovieSearch.NAME);

図書 ワードマッチ:用語、用語、範囲およびその他のクエリを含みます。

//Term Query
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(MovieSearch.NAME, "毒液");

//Terms Query
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(MovieSearch.NAME, "毒液", "我不是药神");

//Range Query      筛选评分在7~10分之间的数据集,includeLower(false)表示from是gt,反之;includeUpper(false)表示to是lt,反之
QueryBuilders.rangeQuery(MovieSearch.SCORE).from(7).to(10).includeLower(false).includeUpper(false);

図書 化合物クエリ

複雑なクエリはでなければならないはず、フィルタ、must_not、を含む、ほとんどのESで使用される、一般的なブールクエリ、ある化合物は、照会、検索APIの弾性検索(クエリDSL)、フィールドベースのクエリ  記事はまた、そのネイティブのスポークを持っていますAPI。ここでブールクエリのコード例の統合された使用であります:

 public void boolDsl() {
        //Bool Query
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //电影名称必须包含我不是药神经过分词后的文本,比如我、不、是、药、神
        boolQueryBuilder.must(QueryBuilders.matchQuery(MovieSearch.NAME, "我不是药神"));

        //排除导演是张三的电影信息
        boolQueryBuilder.mustNot(QueryBuilders.termQuery(MovieSearch.DIRECTORS, "张三"));

        //别名中应该包含药神经过分词后的文本,比如药、神
        boolQueryBuilder.should(QueryBuilders.matchQuery(MovieSearch.ALIAS, "药神"));

        //评分必须大于9(因为es对filter会有智能缓存,推荐使用)
        boolQueryBuilder.filter(QueryBuilders.rangeQuery(MovieSearch.SCORE).gt(9));

        //name、actors、introduction、alias、label 多字段匹配"药神",或的关系
        boolQueryBuilder.filter(QueryBuilders.multiMatchQuery("药神", MovieSearch.NAME, MovieSearch.ACTORS, MovieSearch.INTRODUCTION, MovieSearch.ALIAS, MovieSearch.LABEL));

        String[] includes = {MovieSearch.NAME, MovieSearch.ALIAS, MovieSearch.SCORE, MovieSearch.ACTORS, MovieSearch.DIRECTORS, MovieSearch.INTRODUCTION};
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(INDEX).setTypes(TYPE).setQuery(boolQueryBuilder).addSort(MovieSearch.SCORE, SortOrder.DESC).setFrom(0).setSize(10).setFetchSource(includes, null);
        SearchResponse searchResponse = searchRequestBuilder.get();
        if (!RestStatus.OK.equals(searchResponse.status())) {
            return;
        }
        for (SearchHit searchHit : searchResponse.getHits()) {
            String name = (String) searchHit.getSource().get(MovieSearch.NAME);
            //TODO
        }
    }

メイドESに基づいて、検索エンジンは、これらの基本的なAPIに基づいたプロジェクトのデモ、機能が比較的単純で、ユーザーが入力したテキストは、次の画像に基づいてリアルタイム検索データセットでESを行くことができるということです。

プロジェクトのGitHub:https://github.com/simonsfan/springboot-quartz-demo支店:feature_es注:このプロジェクトが実証することである前にあるので機能「を使用すると、カスタマイズされた定期的なタスクを実装する水晶」、その必要性のカフカサービス、および弾性検索サービスをインストールします。興味のあるパートナーが自分の少し下を向上させることができ、プロジェクトの完璧に多くの問題があります。質問は、メッセージ交換を残してください持っています!


図書 前: 弾性検索ページネーションショー

図書 次へ:弾性検索とmysqlのデータ同期方式

図書 参考:公式サイトをES https://www.elastic.co/guide/en/elasticsearch/client/java-api/6.3/index.html

公開された202元の記事 ウォンの賞賛571 ビュー147万+

おすすめ

転載: blog.csdn.net/fanrenxiang/article/details/86509688