elasticsearch系列-Java客户端的查询操作

在上一篇中,我们介绍了如何使用Java客户端对elasticsearch进行索引的创建、mapping信息的设置和文档的添加,在本篇中我们将主要介绍通过Java客户端查询文档的操作。

使用Java客户端查询操作步骤
  • 创建一个client对象
  • 创建一个查询对象,通过QueryBuilders进行创建,其由很多实现的子类。
  • 使用client执行查询操作,需提前设置查询参数
  • 得到查询返回的结果,默认返回十条数据(如果返回条数过多,可能会导致内存溢出)。通过返回接口可以取查询结果的记录数,去查询结果列表等信息。
  • 关闭client对象。
根据ID查询文档

通过前面的学习,我们知道在添加文档时,elasticsearch会持有一个主键即"_id"。在查询时可以通过这个主键进行查询,示例demo如下所示。

    @Test
    public void queryById() throws UnknownHostException {
        ElasticSearchParams elasticSearchParams = new ElasticSearchParams();
        elasticSearchParams.setIndexName("20200128-xinghaol")
                .setIp("47.107.90.36")
                .setClusterName("my-elasticsearch")
                .setPort(9300);
        SearchResponse searchResponse = ElasticSearchUtil.queryById(elasticSearchParams);
        SearchHits searchHits = searchResponse.getHits();
        System.out.println("总数:" + searchHits.getTotalHits());
        SearchHit[] hits = searchHits.getHits();
        for (int i = 0; i < hits.length; i++) {
            SearchHit searchHit = hits[i];
            System.out.println("查询结果为:" + (i + 1) + " " + searchHit.getSourceAsString());
        }
    }

    public static SearchResponse queryById(ElasticSearchParams elasticSearchParams) throws UnknownHostException {
        TransportClient transportClient = buildTransportClient(elasticSearchParams);
        // 需要加判空
        // 查询id为1的记录
        QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1");
        SearchResponse searchResponse = transportClient.prepareSearch(elasticSearchParams.getIndexName())
                .setTypes(elasticSearchParams.getDocumentTypes())
                .setQuery(queryBuilder)
                .get();

        return searchResponse;
    }

    private static TransportClient buildTransportClient(ElasticSearchParams elasticSearchParams) throws UnknownHostException {
        if (Objects.isNull(elasticSearchParams) || Strings.isNullOrEmpty(elasticSearchParams.getIndexName())
                || Strings.isNullOrEmpty(elasticSearchParams.getIp())
                || Objects.isNull(elasticSearchParams.getPort())
                || Strings.isNullOrEmpty(elasticSearchParams.getClusterName())
                || elasticSearchParams.getPort() <= 0) {
            log.error("参数不合法");
            return null;
        }
        // 创建Settings
        Settings settings = Settings.builder()
                .put("cluster.name", elasticSearchParams.getClusterName())
                .put("client.transport.ignore_cluster_name", true)
                .build();

        // 创建transportclient对象
        TransportClient transportClient = new PreBuiltTransportClient(settings);
        transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName(elasticSearchParams.getIp()), elasticSearchParams.getPort()));

        return transportClient;
    }

在SearchResponse对象中可以得到查询结果的各种信息,比如文档总条数、文档内容等。

根据Term方式查询

根据Trem方式查询与根据ID查询唯一的区别点在于在创建QueryBuilder时为termQuery(name,value)形式的实现方式,如下所示。

QueryBuilder queryBuilder = QueryBuilders.termQuery(elasticSearchParams.getTermQueryName(), elasticSearchParams.getTermQueryValue());

在得到SearchResponse后,与根据ID查询的后续操作相同,这里不再赘述。

根据QueryString查询

在前面介绍elasticsearch查询方式时,elasticsearch支持根据字符串的查询,Java客户端同样支持根据字符串的查询。在创建QueryBuilder时选择queryStringQuery()的实现方式,可以指定默认的搜索域,若不指定搜索域则在所有的与进行查询操作,其他操作不在赘述。

查询elasticsearch分页设置

在上面的查询操作中,我们介绍了elasticsearch默认是返回10条查询数据,但是如果我们想要查询更多或者分页查询操作该怎么办?在Java客户端中transprotClient查询之前设置起始行号和每页显示的条数,示例如下。

 transportClient.prepareSearch(elasticSearchParams.getIndexName())
                    .setTypes(elasticSearchParams.getDocumentTypes())
                    .setFrom(elasticSearchParams.getFrom())
                    .setSize(elasticSearchParams.getSize())
                    .setQuery(queryBuilder);
在查询结果中高亮显示

在使用百度、Google等搜索引擎时,查询出的结果都高亮显示了我们搜索的关键字,在elasticsearch中同样支持高亮的设置。在查询时需要指定一个高亮显示的字段,并且需要指定高亮显示的前缀和后缀,并将这些设置到client中,查询得到结果后可以查看高亮显示的结果。

使用HighlightBuilder设置要高亮的字段名称,以及要添加的前缀、后缀名称。在查询之前设置HighlightBuilder到transportClient中,实例代码如下所示。

    @Test
    public void queryHighLighter() throws UnknownHostException {
        ElasticSearchParams elasticSearchParams = new ElasticSearchParams();
        elasticSearchParams.setIndexName("20200126-xinghaol")
                .setIp("47.107.90.36")
                .setClusterName("my-elasticsearch")
                .setPort(9300);
        TransportClient transportClient = ElasticSearchUtil.obtainTransport(elasticSearchParams);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("house_name");
        highlightBuilder.preTags("<em>");
        highlightBuilder.postTags("</em>");

        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("小屋").defaultField("house_name");

        SearchResponse searchResponse = transportClient.prepareSearch().
                setQuery(queryBuilder).
                highlighter(highlightBuilder).get();

        SearchHits searchHits = searchResponse.getHits();
        SearchHit[] hits = searchHits.getHits();
        for (int i = 0; i < hits.length; i++) {
            SearchHit searchHit = hits[i];
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("house_name");
            Text[] fragments = highlightField.getFragments();
            if (fragments != null) {
                System.out.println("当前是第" + i + "个文档,文档内容:" + fragments[0].toString());
            }
        }
    }

运行上面demo示例得到如下结果,可以看到分词后的都已经加上了<em>标签,即完成了高亮显示的要求。

当前是第0个文档,文档内容:<em>小</em>数点价格房<em>屋</em>01
当前是第1个文档,文档内容:龙卷风<em>小屋</em>
当前是第2个文档,文档内容:爱的<em>小屋</em>
当前是第3个文档,文档内容:这是我修改的房<em>屋</em>名称
当前是第4个文档,文档内容:闪订房<em>屋</em>20200119

小节

在本篇中我们通过Java客户端完成了根据ID、关键词、字符串的查询方式,还介绍了elasticsearch中的分页设置及高亮显示的查询。希望对初学者有所帮助。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值