avatar


3.基于Java操作

关于"基于Java操作",我们主要讨论如何基于Java建立连接,以及如何查询等。
至于如何建立索引等,我们不会讨论。因为一般在企业中,不会用Java去建索引,导数据等。

连接

建立连接查看索引

我们直接看建立连接的代码。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.kakawanyifan;

import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

public class ElasticSearchConn {
public static void main(String[] args) {
// 创建ES客户端
// ES服务端集群地址 多个机器用,分隔
String esServerIps = "11.14.10.1:9300,11.14.10.20:9300,11.14.10.3:9300";
// 集群名称
String clusterName = "dmcpes";
// 设置集群名称
Settings settings = Settings.builder().put("cluster.name", clusterName).build();
// 创建Client
// TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
TransportClient transportClient = new PreBuiltTransportClient(settings);
String esIps[] = esServerIps.split(",");
for (String esIp : esIps) {
// 添加集群IP列表
String[] ipPort = esIp.split(":");
TransportAddress transportAddress = new TransportAddress(InetAddresses.forString(ipPort[0]), Integer.valueOf(ipPort[1]));
transportClient.addTransportAddress(transportAddress);
}
// 获取所有的index
GetIndexResponse response = transportClient.admin().indices().prepareGetIndex().execute().actionGet();
System.out.println(response.getIndices().length);
String[] indices = response.getIndices();
for(String indice : indices){
System.out.println(indice);
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
35
s_es_n000_sys_param_schema_v
ent_union_ent_test1
s_es_n020_cdsy_secucode_v

【部分运行结果略】

jd_goods
ent_history_name
cisp_ent_union_ent

解释说明:

  • TransportClient,基于TCP连接,利用9300端口。有且仅有一个实现类PreBuiltTransportClient
  • PreBuiltTransportClientSettings是客户端的配置,如果采取默认设置,可以填入Settings.EMPTY
    对于集群,一般需要填写的集群名称,如果集群名称不对,连接不上。
    可以通过.put("client.transport.ignore_cluster_name", true),忽略集群名字验证。
  • transportClient.addTransportAddress(transportAddress);,为添加节点地址。
  • transportClient.admin().indices().prepareGetIndex().execute().actionGet(),获取index数组。

查看索引mapping

通过如下的代码可以查看索引的mapping。

1
transportClient.admin().indices().getMappings(new GetMappingsRequest().indices(indice)).get()

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.kakawanyifan;

import java.util.concurrent.ExecutionException;

import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import com.carrotsearch.hppc.cursors.ObjectObjectCursor;

// 如何连接ElasticSearch
public class ElasticSearchConn {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建ES客户端
// ES服务端集群地址 多个机器用,分隔
String esServerIps = "11.14.10.1:9300,11.14.10.20:9300,11.14.10.3:9300";
// 集群名称
String clusterName = "dmcpes";
// 设置集群名称
Settings settings = Settings.builder().put("cluster.name", clusterName).build();
// 创建Client
// TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
TransportClient transportClient = new PreBuiltTransportClient(settings);
String esIps[] = esServerIps.split(",");
for (String esIp : esIps) {
// 添加集群IP列表
String[] ipPort = esIp.split(":");
TransportAddress transportAddress = new TransportAddress(InetAddresses.forString(ipPort[0]), Integer.valueOf(ipPort[1]));
transportClient.addTransportAddress(transportAddress);
}

String indice = "s_es_n043_trs_news_wwn_expld";
GetMappingsResponse res = transportClient.admin().indices().getMappings(new GetMappingsRequest().indices(indice)).get();
ImmutableOpenMap<String, MappingMetaData> mapping = res.mappings().get(indice);
for (ObjectObjectCursor<String, MappingMetaData> c : mapping) {
System.out.println("type = "+c.key);
System.out.println("columns = "+c.value.source());
}
}
}

运行结果:

1
2
type = doc
columns = {"doc":{"properties":{"channel":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"create_time":{"type":"date","format":"yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"},"dwh_created_time":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"entfullname":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"groupname":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"infocategory1":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"infocategory2":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"infocategory3":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"infoemtionlabel":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"irhkeybbsnum":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"modify_type":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"pnum":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"prepoint":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"pubtime":{"type":"date","format":"yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"},"range":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"source":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"sufpoint":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"update_time":{"type":"date","format":"yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"}}}}

MatchAllQuery

查询所有,基于MatchAllQueryBuilder

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld").setTypes("doc").setQuery(matchAllQueryBuilder).get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.kakawanyifan;

import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

public class ElasticSearchUtil {
public static TransportClient getTransportClient() {
// 创建ES客户端
// ES服务端集群地址 多个机器用,分隔
String esServerIps = "11.14.10.1:9300,11.14.10.20:9300,11.14.10.3:9300";
// 集群名称
String clusterName = "dmcpes";
// 设置集群名称
Settings settings = Settings.builder().put("cluster.name", clusterName).build();
// 创建Client
// TransportClient transportClient = new PreBuiltTransportClient(Settings.EMPTY);
TransportClient transportClient = new PreBuiltTransportClient(settings);
String esIps[] = esServerIps.split(",");
for (String esIp : esIps) {
// 添加集群IP列表
String[] ipPort = esIp.split(":");
TransportAddress transportAddress = new TransportAddress(InetAddresses.forString(ipPort[0]), Integer.valueOf(ipPort[1]));
transportClient.addTransportAddress(transportAddress);
}
return transportClient;
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:1967937
最大得分:1.0
{"create_time":"2022/01/02 00:37:48","entfullname":"比亚迪股份有限公司","channel":"汽车","modify_type":"I","source":"news","groupname":"APP","irhkeybbsnum":"98270377338816025330","update_time":"2022/01/02 00:37:48","pubtime":"2022/01/02 00:15:28","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 18:10:20","entfullname":"云南大通道资产管理有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"992795df918710eb","update_time":"2022/01/02 18:10:20","pubtime":"2022/01/02 17:24:07","dwh_created_time":"2022-01-04 14:43:04.190296000"}

【部分运行结果略】

{"create_time":"2022/01/02 11:15:22","entfullname":"四会富仕电子科技股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"98a249ab6fec0ca3","update_time":"2022/01/02 11:15:22","pubtime":"2022/01/02 10:24:14","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 13:30:17","entfullname":"国家开发银行","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"98c45de929c8c587","update_time":"2022/01/02 13:30:17","pubtime":"2022/01/02 12:39:56","dwh_created_time":"2022-01-04 14:43:04.190296000"}

解释说明:

  • prepareSearch():传入index,可变参数。
  • setTypes():传入type,可变参数。

那么,为什么我们要通过getHits().getTotalHits())获取总数,通过getHits().getMaxScore())获取最大得分,通过getHits().getHits()获取结果数组呢?

联系我们在上一张的讨论。
示例代码:

1
2
3
4
GET /ems/_doc/_search
{
"query": { "match_all": {} }
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 6,
"max_score" : 1.0,
"hits" : [
{
"_index" : "ems",
"_type" : "_doc",
"_id" : "9o1Bj34BoH8NsaaoSIo9",
"_score" : 1.0,
"_source" : {
"name" : "罗纳尔多",
"age" : 43,
"bir" : "2012-12-12",
"content" : "世上只有一个罗纳尔多!",
"address" : "杭州"
}
},

【部分运行结果略】

{
"_index" : "ems",
"_type" : "_doc",
"_id" : "841Bj34BoH8NsaaoSIo9",
"_score" : 1.0,
"_source" : {
"name" : "范德萨",
"age" : 24,
"bir" : "2012-12-12",
"content" : "再见,范德萨,不老的传说,曼联有你,一生有你。",
"address" : "上海"
}
}
]
}
}

一样的结构

From-Size-Sort

分页查询基于三个方法:

  1. setFrom()
  2. setSize()
  3. addSort()

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
// prepareSearch() index
// setTypes() type
// setQuery() 查询条件
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc").setQuery(matchAllQueryBuilder)
.setFrom(0)
.setSize(20)
.addSort("pubtime",SortOrder.DESC)
.get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:1967937
最大得分:NaN
{"create_time":"2022/01/03 01:10:51","entfullname":"北京青年报社","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"68c07dc361d38aef","update_time":"2022/01/03 01:10:51","pubtime":"2022/01/02 23:59:59","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/03 01:25:22","entfullname":"北京快手科技有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"69d255bd931ac939","update_time":"2022/01/03 01:25:22","pubtime":"2022/01/02 23:59:59","dwh_created_time":"2022-01-04 14:43:04.190296000"}

【部分运行结果略】

{"create_time":"2022/01/03 00:41:20","entfullname":"联想集团有限公司","channel":"微博","modify_type":"I","source":"wb","groupname":"微博","irhkeybbsnum":"4721342357701619","update_time":"2022/01/03 00:41:20","pubtime":"2022/01/02 23:59:59","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/03 01:25:22","entfullname":"上海新世界股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"69d255bd931ac939","update_time":"2022/01/03 01:25:22","pubtime":"2022/01/02 23:59:59","dwh_created_time":"2022-01-04 14:43:04.190296000"}

解释说明:

  • setFrom(起始条数):起始条数
  • setSize(每页条数):每页条数
  • addSort(排序字段,排序方式):排序
    • SortOrder.DESC:降序
    • SortOrder.ASC:升序
  • 因为我们指定了排序方式,干预了ES的默认排序方式,所以最大得分为NaN

TermQuery

关键词查询基于TermQueryBuilder

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("irhkeybbsnum", "98270377338816025330");
// prepareSearch() index
// setTypes() type
// setQuery() 查询条件
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld").setTypes("doc").setQuery(termQueryBuilder).get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:12
最大得分:12.305103
{"create_time":"2022/01/02 00:37:48","entfullname":"上汽通用五菱汽车股份有限公司","channel":"汽车","modify_type":"I","source":"news","groupname":"APP","irhkeybbsnum":"98270377338816025330","update_time":"2022/01/02 00:37:48","pubtime":"2022/01/02 00:15:28","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"sufpoint":"[{\"index\":\"69\",\"word\":\"为\"},{\"index\":\"82\",\"word\":\"服务\"}]","pnum":"18","create_time":"2022/01/02 00:37:48","infoemtionlabel":"正面","entfullname":"华为投资控股有限公司","channel":"汽车","range":"7","modify_type":"I","source":"news","prepoint":"[{\"index\":\"75\",\"word\":\"华为\"}]","groupname":"APP","irhkeybbsnum":"98270377338816025330","update_time":"2022/01/02 00:37:48","pubtime":"2022/01/02 00:15:28","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}

【部分运行结果略】

{"create_time":"2022/01/02 00:37:48","entfullname":"比亚迪股份有限公司","channel":"汽车","modify_type":"I","source":"news","groupname":"APP","irhkeybbsnum":"98270377338816025330","update_time":"2022/01/02 00:37:48","pubtime":"2022/01/02 00:15:28","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"sufpoint":"[{\"index\":\"69\",\"word\":\"为\"},{\"index\":\"82\",\"word\":\"服务\"}]","pnum":"18","create_time":"2022/01/02 00:37:48","infoemtionlabel":"正面","entfullname":"北京汽车集团有限公司","channel":"汽车","range":"59","modify_type":"I","source":"news","prepoint":"[{\"index\":\"23\",\"word\":\"北汽\"}]","groupname":"APP","irhkeybbsnum":"98270377338816025330","update_time":"2022/01/02 00:37:48","pubtime":"2022/01/02 00:15:28","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}

再来一个,我们查entfullname上汽通用五菱汽车股份有限公司的数据。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("entfullname", "上汽通用五菱汽车股份有限公司");

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld").setTypes("doc").setQuery(termQueryBuilder).get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
总记录数:0
最大得分:NaN

没有?
这不奇怪,因为我们的entfullnametext类型的,被分词了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"doc": {
"properties": {

【部分运行结果略】

"entfullname": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},

【部分运行结果略】

}
}
}

我们发现,这个entfullname内部还有一个keyword类的。
来,我们把QueryBuilders.termQuery("entfullname", "上汽通用五菱汽车股份有限公司");中的entfullname,改成entfullname.keyword

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("entfullname.keyword", "上汽通用五菱汽车股份有限公司");
// setQuery() 查询条件
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld").setTypes("doc").setQuery(termQueryBuilder).get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:292
最大得分:8.89208
{"create_time":"2022/01/02 18:50:41","entfullname":"上汽通用五菱汽车股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"579147f7cb643199","update_time":"2022/01/02 18:50:41","pubtime":"2022/01/02 18:06:48","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 15:55:37","entfullname":"上汽通用五菱汽车股份有限公司","channel":"更多_财经","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"27744102977017848960","update_time":"2022/01/02 15:55:37","pubtime":"2022/01/02 15:41:25","dwh_created_time":"2022-01-04 14:43:04.190296000"}

【部分运行结果略】

{"create_time":"2022/01/02 10:22:42","entfullname":"上汽通用五菱汽车股份有限公司","channel":"资讯","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"131134992095847433650","update_time":"2022/01/02 10:22:42","pubtime":"2022/01/02 10:03:21","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 01:50:23","entfullname":"上汽通用五菱汽车股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"2c93c0036de72c29","update_time":"2022/01/02 01:50:23","pubtime":"2022/01/02 01:03:57","dwh_created_time":"2022-01-04 14:43:04.190296000"}

MatchPhraseQuery

或者利用MatchPhraseQueryBuilder,其首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含全部搜索词项,且位置与搜索词项相同的文档。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("entfullname", "上汽通用五菱汽车股份有限公司");
// setQuery() 查询条件
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld").setTypes("doc").setQuery(matchPhraseQueryBuilder).get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:298
最大得分:34.461597
{"create_time":"2022/01/02 13:59:29","entfullname":"上汽通用五菱汽车股份有限公司","channel":"推荐","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"6465313100016337020","update_time":"2022/01/02 13:59:29","pubtime":"2022/01/02 13:18:15","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 11:20:17","entfullname":"上汽通用五菱汽车股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"cbe87c0fabf26847","update_time":"2022/01/02 11:20:17","pubtime":"2022/01/02 10:37:12","dwh_created_time":"2022-01-04 14:43:04.190296000"}

【部分运行结果略】

{"create_time":"2022/01/02 11:00:28","entfullname":"上汽通用五菱汽车股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"3e1536a4960de062","update_time":"2022/01/02 11:00:28","pubtime":"2022/01/02 10:10:19","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"sufpoint":"[{\"index\":\"77\",\"word\":\"供应商\"}]","pnum":"34","create_time":"2022/01/02 08:27:31","infoemtionlabel":"正面","entfullname":"上汽通用五菱汽车股份有限公司","channel":"(002466)天齐锂业","range":"10","modify_type":"I","source":"news","prepoint":"[{\"index\":\"67\",\"word\":\"上汽通用五菱\"}]","groupname":"国内论坛","irhkeybbsnum":"151758632255815847961","update_time":"2022/01/02 08:27:31","pubtime":"2022/01/02 08:24:15","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}

TermsQuery

TermsQuery,类似于SQL中的in

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.SearchHit;


public class ElasticSearchTest {
public static void main(String[] args) {

TransportClient transportClient = ElasticSearchUtil.getTransportClient();

String[] entNameArr = "上汽通用五菱汽车股份有限公司,比亚迪股份有限公司,北京汽车集团有限公司,上海汽车集团股份有限公司".split(",");
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("entfullname.keyword", entNameArr);

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc")
.setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(termsQueryBuilder)
.get();

SearchHit[] searchHits = searchResponse.getHits().getHits();

for (SearchHit searchHit : searchHits) {
// 原始数据
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
{"eid":"q4dfba4f9b2df43838fe2752e16784931","create_time":"2022/01/16 17:15:25","entfullname":"上海汽车集团股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"d3f08a909e7bc473","update_time":"2022/01/16 17:15:25","pubtime":"2022/01/16 16:29:31","dwh_created_time":"2022-01-17 22:10:31.520690000"}
{"create_time":"2022/01/02 23:20:36","entfullname":"比亚迪股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"6352f0c546511898","update_time":"2022/01/02 23:20:36","pubtime":"2022/01/02 22:25:48","dwh_created_time":"2022-01-04 14:43:04.190296000"}

【部分运行结果略】

{"create_time":"2022/01/02 15:05:19","entfullname":"比亚迪股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"5e103055b777b064","update_time":"2022/01/02 15:05:19","pubtime":"2022/01/02 14:15:45","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"eid":"q4fed889ac6a6f0def455dc1eda4960cc","create_time":"2022/01/18 08:30:16","entfullname":"北京汽车集团有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"b02492b2c58e075b","update_time":"2022/01/18 08:30:16","pubtime":"2022/01/18 07:45:00","credit_code":"911100001011596199","dwh_created_time":"2022-01-19 18:10:13.658066000"}

RangeQuery

范围查询基于RangeQueryBuilder及其四个相关方法:

  1. lt:小于
  2. lte:小于等于
  3. gt:大于
  4. gte:大于等于

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("pubtime").format("yyyy-MM-dd").lte("2022-01-02");
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc").setQuery(rangeQueryBuilder)
.setFrom(0)
.setSize(20)
.addSort("pubtime",SortOrder.ASC)
.get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:1967937
最大得分:NaN
{"create_time":"2022/01/02 15:02:29","entfullname":"恒大集团有限公司","channel":"资讯","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"78053865932424541630","update_time":"2022/01/02 15:02:29","pubtime":"2022/01/02 00:00:00","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 11:45:47","entfullname":"中国第一汽车集团有限公司","channel":"招标中心_免费招标信息","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"70633513706740423100","update_time":"2022/01/02 11:45:47","pubtime":"2022/01/02 00:00:00","dwh_created_time":"2022-01-04 14:43:04.190296000"}

【部分运行结果略】

{"create_time":"2022/01/02 15:30:48","entfullname":"上海良网工程材料有限公司","channel":"投票新闻","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"54095407676301755840","update_time":"2022/01/02 15:30:48","pubtime":"2022/01/02 00:00:00","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 15:30:48","entfullname":"唐山市曹妃甸区航盛商贸有限公司","channel":"投票新闻","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"54095407676301755840","update_time":"2022/01/02 15:30:48","pubtime":"2022/01/02 00:00:00","dwh_created_time":"2022-01-04 14:43:04.190296000"}

解释说明:

  • 对于时间,需要利用format("yyyy-MM-dd"),转换成相同格式才能比较。

WildcardQuery

通配符查询,基于WildcardQueryBuilder及其两个符号。

  1. *:所有
  2. ?:一个

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("entfullname", "上海*");
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc").setQuery(wildcardQueryBuilder)
.setFrom(0)
.setSize(5)
.addSort("pubtime",SortOrder.ASC)
.get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
总记录数:0
最大得分:NaN

查不到?也是因为被分词了。

PrefixQuery

PrefixQuery,查找含有指定前缀的关键词的相关文档。
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.PrefixQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("entfullname.keyword", "上海");
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc").setQuery(prefixQueryBuilder)
.setFrom(0)
.setSize(5)
.get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
总记录数:97062
最大得分:1.0
{"create_time":"2022/01/02 07:35:27","entfullname":"上海节节高投资管理有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"a193ac3802ec76c6","update_time":"2022/01/02 07:35:27","pubtime":"2022/01/02 07:00:00","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 17:45:15","entfullname":"上海节节高投资管理有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"a1b094815df3c8d6","update_time":"2022/01/02 17:45:15","pubtime":"2022/01/02 16:50:53","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 17:50:20","entfullname":"上海天天基金销售有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"a1de313f5e756862","update_time":"2022/01/02 17:50:20","pubtime":"2022/01/02 17:07:04","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 12:45:22","entfullname":"上海移芯通信科技有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"a218877a646b9a19","update_time":"2022/01/02 12:45:22","pubtime":"2022/01/02 11:58:21","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"create_time":"2022/01/02 12:45:22","entfullname":"上海新世界股份有限公司","channel":"","modify_type":"I","source":"wx","groupname":"微信","irhkeybbsnum":"a2a50540b473a097","update_time":"2022/01/02 12:45:22","pubtime":"2022/01/02 11:36:34","dwh_created_time":"2022-01-04 14:43:04.190296000"}

BoolQuery

布尔查询基于BoolQueryBuilder及其四个方法:

  • must():必须匹配must查询条件
  • should():应该匹配should查询中的一个或多个
  • must_not():必须不匹配

must有点类似andshould有点类似or。但只是有点类似,区别我们在上一章《2.基本操作》有过讨论。

通过上述方法,我们可以匹配任何方法。

例如。我们查询

  1. entfullname上汽通用五菱汽车股份有限公司比亚迪股份有限公司北京汽车集团有限公司上海汽车集团股份有限公司
  2. infoEmotion正面
    1. infocategory1经营管理infocategory2战略布局infocategory3战略合作
    2. infocategory1经营管理infocategory2企业项目infocategory3公司项目
  3. groupname国内新闻
  4. pubtime大于等于2022-01-01
  5. pubtime小于等于2022-01-02
  6. 另外,pubtime从近到远,每页10条的第2页

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
// 查询条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// entfullname是"上汽通用五菱汽车股份有限公司"或"比亚迪股份有限公司"或"北京汽车集团有限公司"或"上海汽车集团股份有限公司"
//构造数组,初始化需要匹配的值
String[] entNameArr = new String[]{"上汽通用五菱汽车股份有限公司","比亚迪股份有限公司","北京汽车集团有限公司","上海汽车集团股份有限公司"};
boolQueryBuilder.must(QueryBuilders.termsQuery("entfullname.keyword", entNameArr));
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("infoemtionlabel", "正面"));

// infocategory1是经营管理且infocategory2是战略布局且infocategory3是战略合作
BoolQueryBuilder labelBoolQueryBuilder_1 = QueryBuilders.boolQuery();
labelBoolQueryBuilder_1.must(QueryBuilders.matchPhraseQuery("infocategory1", "经营管理"));
labelBoolQueryBuilder_1.must(QueryBuilders.matchPhraseQuery("infocategory2", "战略布局"));
labelBoolQueryBuilder_1.must(QueryBuilders.matchPhraseQuery("infocategory3", "战略合作"));

// 或infocategory1是经营管理且infocategory2是企业项目且infocategory3是公司项目
BoolQueryBuilder labelBoolQueryBuilder_2 = QueryBuilders.boolQuery();
labelBoolQueryBuilder_2.must(QueryBuilders.matchPhraseQuery("infocategory1", "经营管理"));
labelBoolQueryBuilder_2.must(QueryBuilders.matchPhraseQuery("infocategory2", "企业项目"));
labelBoolQueryBuilder_2.must(QueryBuilders.matchPhraseQuery("infocategory3", "公司项目"));

BoolQueryBuilder labelBoolQueryBuilder = QueryBuilders.boolQuery();
labelBoolQueryBuilder.should(labelBoolQueryBuilder_1);
labelBoolQueryBuilder.should(labelBoolQueryBuilder_2);

boolQueryBuilder.must(labelBoolQueryBuilder);

// 且groupname是国内新闻
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("groupname", "国内新闻"));

// 且pubtime大于等于2022-01-01
boolQueryBuilder.must(QueryBuilders.rangeQuery("pubtime").format("yyyy-MM-dd").gte("2022-01-01"));
// 且pubtime小于等于2022-01-02
boolQueryBuilder.must(QueryBuilders.rangeQuery("pubtime").format("yyyy-MM-dd").lte("2022-01-02"));

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc").setQuery(boolQueryBuilder)
.setFrom((2-1) * 10)
.setSize(10)
.addSort("pubtime", SortOrder.DESC)
.get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
总记录数:389
最大得分:NaN
{"sufpoint":"[{\"index\":\"77\",\"word\":\"合资\"}]","pnum":"79","create_time":"2022/01/02 23:00:26","infoemtionlabel":"正面","entfullname":"上海汽车集团股份有限公司","channel":"股市资讯","range":"48","modify_type":"I","source":"news","prepoint":"[{\"index\":\"29\",\"word\":\"上汽集团\"}]","groupname":"国内新闻","irhkeybbsnum":"19435560250330495330","update_time":"2022/01/02 23:00:26","pubtime":"2022/01/02 22:58:50","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}
{"sufpoint":"[{\"index\":\"50\",\"word\":\"项目\"}]","pnum":"16","create_time":"2022/01/02 22:49:45","infoemtionlabel":"正面","entfullname":"比亚迪股份有限公司","channel":"配资知识","range":"13","modify_type":"I","source":"news","prepoint":"[{\"index\":\"37\",\"word\":\"比亚迪\"}]","groupname":"国内新闻","irhkeybbsnum":"123907527053406436820","update_time":"2022/01/02 22:49:45","pubtime":"2022/01/02 22:47:03","infocategory2":"企业项目","infocategory3":"公司项目","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}

【部分运行结果略】

{"sufpoint":"[{\"index\":\"31\",\"word\":\"合资\"}]","pnum":"2","create_time":"2022/01/02 23:01:27","infoemtionlabel":"正面","entfullname":"上海汽车集团股份有限公司","channel":"推荐","range":"9","modify_type":"I","source":"news","prepoint":"[{\"index\":\"22\",\"word\":\"上汽集团\"}]","groupname":"国内新闻","irhkeybbsnum":"41817883212480746720","update_time":"2022/01/02 23:01:27","pubtime":"2022/01/02 22:21:50","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}
{"sufpoint":"[{\"index\":\"83\",\"word\":\"供应商\"}]","pnum":"31","create_time":"2022/01/03 13:16:40","infoemtionlabel":"正面","entfullname":"上海汽车集团股份有限公司","channel":"斯巴鲁XV","range":"17","modify_type":"I","source":"news","prepoint":"[{\"index\":\"100\",\"word\":\"上汽集团\"}]","groupname":"国内新闻","irhkeybbsnum":"75656717962601009410","update_time":"2022/01/03 13:16:40","pubtime":"2022/01/02 22:21:00","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}

特别的,将鼠标移动到boolQueryBuilder,可以看到其查询用的JSON脚本。

FetchSource

返回指定字段基于setFetchSource()方法,第一个参数为包含哪些字段,第二个参数为排除哪些字段。例如

  • setFetchSource("*","age"),返回所有字段,但排除age字段。
  • setFetchSource("name",""),只返回name字段。
  • setFetchSource(new String[]{},new String[]{}),分别指定字段。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
//设置返回哪些字段
String[] includeFields = new String[] {"entfullname"};

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc").setQuery(QueryBuilders.matchAllQuery())
.setFetchSource(includeFields, null)
.get();
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
总记录数:1967937
最大得分:1.0
{"entfullname":"杭州市钱江新城投资集团有限公司"}
{"entfullname":"浏阳河集团股份有限公司"}
{"entfullname":"美的集团股份有限公司"}
{"entfullname":"黑龙江红河谷汽车测试股份有限公司"}
{"entfullname":"海南医学院第二附属医院"}
{"entfullname":"深圳市安吉丽光电科技有限公司"}
{"entfullname":"北京三快在线科技有限公司"}
{"entfullname":"中国电信集团有限公司"}
{"entfullname":"国家电网有限公司"}
{"entfullname":"东阳正午阳光影视有限公司"}

Scroll

那么,如果我们想获取全量数据怎么办?
setFrom(0) setSize(Integer.MaxValue)
不,一般默认from+size不能超过一万。
设置太大的话,会有性能问题。

可以考虑Scroll,滚动搜索。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;

public class ElasticSearchDemo {

public static void main(String[] args) {
TransportClient transportClient = ElasticSearchUtil.getTransportClient();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.existsQuery("infocategory1"));
//设置返回哪些字段
String[] includeFields = new String[] {"infocategory1", "infocategory2", "infocategory3" ,"infoemtionlabel"};

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc")
.setQuery(boolQueryBuilder)
.setFetchSource(includeFields, null)
.setTrackTotalHits(true)
.setSize(10000)
.setScroll(new TimeValue(60000))
.get();
// Scroll until no hits are returned
int count = 0;
do {
// 总记录数
System.out.println("总记录数:" + searchResponse.getHits().getTotalHits());
// 最大得分
System.out.println("最大得分:" + searchResponse.getHits().getMaxScore());
// Hits
SearchHit[] searchHits = searchResponse.getHits().getHits();
for (SearchHit searchHit : searchHits) {
count = count + 1;
System.out.println(searchHit.getSourceAsString());
}
searchResponse = transportClient.prepareSearchScroll(searchResponse.getScrollId())
.setScroll(new TimeValue(60000))
.execute()
.actionGet();
} while (searchResponse.getHits().getHits().length != 0);
System.out.println(count);
}
}

运行结果:

1
2
3
4
5
6
7
8

【部分运行结果略】

{"infoemtionlabel":"负面","infocategory2":"监管风险","infocategory3":"主管部门预警","infocategory1":"公司治理"}
{"infoemtionlabel":"负面","infocategory2":"不正当经营","infocategory3":"违章经营","infocategory1":"经营管理"}
{"infoemtionlabel":"正面","infocategory2":"对外投资借款","infocategory3":"对外投资","infocategory1":"经营管理"}
{"infoemtionlabel":"负面","infocategory2":"监管风险","infocategory3":"主管部门预警","infocategory1":"公司治理"}
214115

Highlight

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.kakawanyifan;

import java.util.Map;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;

public class ElasticSearchTest {
public static void main(String[] args) {

HighlightBuilder highlightBuilder = new HighlightBuilder()
.field("*")
.requireFieldMatch(false)
.preTags("<span style='color:red;'>")
.postTags("</span>");

TransportClient transportClient = ElasticSearchUtil.getTransportClient();

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn")
.setTypes("doc")
.setQuery(QueryBuilders.multiMatchQuery("新", "trsabstract","title"))
.highlighter(highlightBuilder)
.get();

SearchHit[] searchHits = searchResponse.getHits().getHits();

for (SearchHit searchHit : searchHits) {
// 原始数据
// System.out.println(searchHit.getSourceAsString());
// 高亮
Map<String, HighlightField> map = searchHit.getHighlightFields();
for (String key : map.keySet()) {
System.out.println(key);
Text[] texts = map.get(key).fragments();
for (Text text : texts) {
// 这里为了便于查看,去除 \r \n
System.out.println(text.toString().replace("\r", "").replace("\n", ""));
}
System.out.println("\n");
}
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
irauthors
昆山市<span style='color:red;'>新</span>镇中学发布


trskeyworks
<span style='color:red;'>新</span>教师;老师;成长;教学;学期;发言;<span style='color:red;'>新</span>镇;一名;孩子;<span style='color:red;'>新</span>中


trsabstract
<span style='color:red;'>新</span>人<span style='color:red;'>新</span>春<span style='color:red;'>新</span>面貌 <span style='color:red;'>新</span>镇<span style='color:red;'>新</span>岁<span style='color:red;'>新</span>发展。;<span style='color:red;'>新</span>教师与<span style='color:red;'>新</span>中相融,为<span style='color:red;'>新</span>教师提供一个成长进步的平台,“<span style='color:red;'>新</span>教师<span style='color:red;'>新</span>春茶话会”活动在西校区三楼报告厅举行。
<span style='color:red;'>新</span>教师自我介绍言语间展现了<span style='color:red;'>新</span>教师昂扬向上的精神面貌与积极投身教学事业的教学热情。
<span style='color:red;'>新</span>教师代表发言在这个学期里面学生成长着,”学生处于小初转型的一个学期,作为<span style='color:red;'>新</span>教师,我觉得自己就是一名<span style='color:red;'>新</span>教师,第一次上公开课,就要遵循这个环境里的规则。朱老师以自身教学经历为例,


【部分运行结果略】


trsabstract
【<span style='color:red;'>新</span>年心声】<span style='color:red;'>新</span>年,向人们宣告着<span style='color:red;'>新</span>的一年即将来临。也落在人们肩膀。沉睡的生机不断觉醒,一点点渗透出来,注定属于<span style='color:red;'>新</span>生!然后猛的又把窗户推了回去。
我有直面寒冬的勇气,却似乎还没有做好经受寒冬考验的准备,就像每一个正在经历寒冬的人们一样,在<span style='color:red;'>新</span>的一年,<span style='color:red;'>新</span>年注定属于<span style='color:red;'>新</span>生,<span style='color:red;'>新</span>生又会伴随<span style='color:red;'>新</span>的挑战,却永远无法阻挡我不断向前的脚步和信念。
就像沉睡的生机,永远都会一点点重<span style='color:red;'>新</span>苏醒,就像迎着寒风行走的人们,


title
【<span style='color:red;'>新</span>年心声】<span style='color:red;'>新</span>年,<span style='color:red;'>新</span>生


content
wx_fmt=gif">;关注我们,让你的每一天都更加温暖~清晨醒来,窗外飘雪了,大自然再一次以具象的季节特征,向人们宣告着<span style='color:red;'>新</span>的一年即将来临。
因为<span style='color:red;'>新</span>年,注定属于<span style='color:red;'>新</span>生!面对如此美景,我轻轻拉开窗户,想要突破视觉,更直接的去感受一番。寒风也特别爽快,径直窜进来,给了我一个大大的熊抱,让我不禁颤栗了一下,然后猛的又把窗户推了回去。
我有直面寒冬的勇气,却似乎还没有做好经受寒冬考验的准备,就像每一个正在经历寒冬的人们一样,在<span style='color:red;'>新</span>的一年,我们大概都需要<span style='color:red;'>新</span>生。
是的,<span style='color:red;'>新</span>年注定属于<span style='color:red;'>新</span>生,<span style='color:red;'>新</span>生又会伴随<span style='color:red;'>新</span>的挑战,<span style='color:red;'>新</span>的挑战,或许会让我暂时停滞不前,却永远无法阻挡我不断向前的脚步和信念。
就像沉睡的生机,永远都会一点点重<span style='color:red;'>新</span>苏醒,就像迎着寒风行走的人们,一定会再次扬起头,露出灿烂的笑容,我也必将重燃意志,奔向<span style='color:red;'>新</span>年,迎来<span style='color:red;'>新</span>生!

MultiMatchQuery

MultiMatchQuery,一个查询关键词,和多个字段进行匹配。
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;


public class ElasticSearchTest {
public static void main(String[] args) {

TransportClient transportClient = ElasticSearchUtil.getTransportClient();

MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("新", "title","content");

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn")
.setTypes("doc")
.setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(matchQueryBuilder)
.get();

SearchHit[] searchHits = searchResponse.getHits().getHits();

for (SearchHit searchHit : searchHits) {
// 原始数据
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
{"create_time":"2022/01/02 23:20:25","channel":"微博","modify_type":"I","trsabstract":"始终都要开始新的生活呀 临沂·临沂上海路万达广场 http://t.cn/AiEZnMdz","urlcontent":"5aeL57uI6YO96KaB5byA5aeL5paw55qE55Sf5rS75ZGAIOS4tOaygsK35Li05rKC5LiK5rW36Lev\r\n5LiH6L6+5bm/5Zy6IGh0dHA6Ly90LmNuL0FpRVpuTWR6","source":"wb","title":"","groupname":"微博","content":"始终都要开始新的生活呀 临沂·临沂上海路万达广场 http://t.cn/AiEZnMdz","url":"http://weibo.com/6359885207/L8WSmivji","savetime":"2022/01/02 23:20:25","irhkeybbsnum":"4721329464410264","irauthors":"香菜给你吃x","update_time":"2022/01/02 23:20:25","irsrcname":"","pubtime":"2022/01/02 23:08:44","sitename":"新浪","trskeyworks":"临沂;上海路;万达;新的;广场;http;都要;AiEZnMdz;始终","dwh_created_time":"2022-01-04 14:43:27.304132000","urldate":"2022/01/02 00:00:00"}

【部分运行结果略】

{"create_time":"2022/01/03 00:35:26","channel":"微博","modify_type":"I","trsabstract":"戳\u003e\u003e\u003e 奇遇无线蓝牙耳机颈挂脖入耳式运动跑步型大电量2021年新款超长待机续航男款女士适用于华为 http://t.cn/A6IXWFXm","urlcontent":"MjAyMuW5tDHmnIgy5pelMjPml7Y1NOWIhjQx56eSOE1vUUEgLy9A5Ymn6L+35LiA5ZOlOjI5Ljnj\r\ngJDniLHlpYfoibrjgJHmmbrog73mjILohJbok53niZnogLPmnLog5pm66IO95oyC6ISW6JOd54mZ\r\n6ICz5py6MjkuOeWFg+aKou+8gSDmiLM+Pj4g5aWH6YGH5peg57q/6JOd54mZ6ICz5py66aKI5oyC\r\n6ISW5YWl6ICz5byP6L+Q5Yqo6LeR5q2l5Z6L5aSn55S16YePMjAyMeW5tOaWsOasvui2hemVv+W+\r\nheacuue7reiIqueUt+asvuWls+Wjq+mAgueUqOS6juWNjuS4uiBodHRwOi8vdC5jbi9BNklYV0ZY\r\nbQ\u003d\u003d","source":"wb","title":"","groupname":"微博","content":"2022年1月2日23时54分41秒8MoQA //@剧迷一哥:29.9【爱奇艺】智能挂脖蓝牙耳机 智能挂脖蓝牙耳机29.9元抢! 戳\u003e\u003e\u003e 奇遇无线蓝牙耳机颈挂脖入耳式运动跑步型大电量2021年新款超长待机续航男款女士适用于华为 http://t.cn/A6IXWFXm","url":"http://weibo.com/6529007776/L8XbRrEzT","savetime":"2022/01/03 00:35:26","irhkeybbsnum":"4721341556590841","irauthors":"熊妹爱追剧","update_time":"2022/01/03 00:35:26","irsrcname":"","pubtime":"2022/01/02 23:56:48","sitename":"新浪","trskeyworks":"耳机;蓝牙;女士;男款;入耳式;续航;运动;待机;跑步;超长","dwh_created_time":"2022-01-04 14:43:27.304132000","urldate":"2022/01/02 00:00:00"}

FuzzyQuery

FuzzyQuery,模糊查询。
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;


public class ElasticSearchTest {
public static void main(String[] args) {

TransportClient transportClient = ElasticSearchUtil.getTransportClient();

FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("entfullname.keyword", "迪迪迪股份有限公司");

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc")
.setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(fuzzyQueryBuilder)
.get();

SearchHit[] searchHits = searchResponse.getHits().getHits();

for (SearchHit searchHit : searchHits) {
// 原始数据
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
{"eid":"q646973a7e3b22b5f56f426c3ca70b843","create_time":"2022/01/18 13:18:23","entfullname":"比亚迪股份有限公司","channel":"推荐","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"55630549005802140670","update_time":"2022/01/18 13:18:23","pubtime":"2022/01/17 10:21:51","credit_code":"91440300192317458F","dwh_created_time":"2022-01-18 22:42:01.658617000"}
{"eid":"q646973a7e3b22b5f56f426c3ca70b843","create_time":"2022/01/16 16:09:38","entfullname":"比亚迪股份有限公司","channel":"车类交易","modify_type":"I","source":"news","groupname":"国内论坛","irhkeybbsnum":"81898118845949722831","update_time":"2022/01/16 16:09:38","pubtime":"2022/01/16 15:48:37","credit_code":"91440300192317458F","dwh_created_time":"2022-01-17 22:10:31.520690000"}

【部分运行结果略】

{"create_time":"2022/01/02 08:39:29","entfullname":"比亚迪股份有限公司","channel":"新闻","modify_type":"I","source":"news","groupname":"国内新闻","irhkeybbsnum":"77638593660404418820","update_time":"2022/01/02 08:39:29","pubtime":"2022/01/02 08:00:00","dwh_created_time":"2022-01-04 14:43:04.190296000"}
{"eid":"q646973a7e3b22b5f56f426c3ca70b843","create_time":"2022/01/18 17:45:51","entfullname":"比亚迪股份有限公司","channel":"新能源车吧","modify_type":"I","source":"news","groupname":"国内论坛","irhkeybbsnum":"37841173395764149081","update_time":"2022/01/18 17:45:51","pubtime":"2022/01/18 17:41:29","credit_code":"91440300192317458F","dwh_created_time":"2022-01-19 18:10:13.658066000"}

Collapse

根据指定的字段,进行折叠。类似于SQL中的distinct
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.sort.SortOrder;


public class ElasticSearchTest {
public static void main(String[] args) {

TransportClient transportClient = ElasticSearchUtil.getTransportClient();

CollapseBuilder collapseBuilder = new CollapseBuilder("irhkeybbsnum.keyword");
SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc")
.setFrom((2-1) * 10)
.setSize(10)
.addSort("pubtime", SortOrder.DESC)
.setFetchSource(new String[] {"irhkeybbsnum","pubtime"}, null)
.setCollapse(collapseBuilder)
.get();

SearchHit[] searchHits = searchResponse.getHits().getHits();

for (SearchHit searchHit : searchHits) {
// 原始数据
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
{"irhkeybbsnum":"4727140559358332","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"2e2e9cfeea9dabfc","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"a704ef151030c56e","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"41ef19f1efd114de","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"afc06005ded60e1b","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"4727140560668462","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"67632385405980755090","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"4727140560668859","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"4727140559884172","pubtime":"2022/01/18 23:59:58"}
{"irhkeybbsnum":"c0eca90be8d5b99d","pubtime":"2022/01/18 23:59:58"}

查询方法很多,我们不可能穷尽所有的查询方法,还有多字段分词查询(QueryStringQuery)、ids查询(IdsQuery)等,很多方法,我们没有讨论。

Filter

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.kakawanyifan;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.ExistsQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;


public class ElasticSearchTest {
public static void main(String[] args) {

TransportClient transportClient = ElasticSearchUtil.getTransportClient();

ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery("infocategory1");

SearchResponse searchResponse = transportClient.prepareSearch("s_es_n043_trs_news_wwn_expld")
.setTypes("doc")
.setQuery(QueryBuilders.matchAllQuery())
.setPostFilter(existsQueryBuilder)
.get();

SearchHit[] searchHits = searchResponse.getHits().getHits();

for (SearchHit searchHit : searchHits) {
// 原始数据
System.out.println(searchHit.getSourceAsString());
}
}
}

运行结果:

1
2
3
4
5
6
7
{"sufpoint":"[{\"index\":\"57\",\"word\":\"合作\"}]","pnum":"23","create_time":"2022/01/02 22:42:28","infoemtionlabel":"正面","entfullname":"中国航空工业集团有限公司","channel":"合肥","range":"31","modify_type":"I","source":"news","prepoint":"[{\"index\":\"26\",\"word\":\"中国航空工业集团\"}]","groupname":"国内新闻","irhkeybbsnum":"60582722411432775190","update_time":"2022/01/02 22:42:28","pubtime":"2022/01/02 22:26:26","infocategory2":"战略布局","infocategory3":"战略合作","dwh_created_time":"2022-01-04 14:43:04.190296000","infocategory1":"经营管理"}
{"sufpoint":"[{\"index\":\"12\",\"word\":\"涨停\"}]","eid":"q349a23fa383d1bd8f271f951cd373657","pnum":"3","create_time":"2022/01/16 19:03:17","infoemtionlabel":"正面","entfullname":"湛江国联水产开发股份有限公司","channel":"首页","range":"12","modify_type":"I","source":"news","prepoint":"[{\"index\":\"0\",\"word\":\"国联水产\"}]","groupname":"国内新闻","irhkeybbsnum":"95157840155748306020","update_time":"2022/01/16 19:03:17","pubtime":"2022/01/16 18:58:00","credit_code":"91440800727060629M","infocategory2":"企业股份","infocategory3":"股价波动","dwh_created_time":"2022-01-17 22:10:31.520690000","infocategory1":"公司治理"}

【部分运行结果略】

{"sufpoint":"[{\"index\":\"23\",\"word\":\"增资扩股\"}]","eid":"qbb1bfb17b11b79a5184c69804c86910f","pnum":"51","create_time":"2022/01/17 02:06:30","infoemtionlabel":"正面","entfullname":"广东南粤银行股份有限公司","channel":"财经_基金_财经头条","range":"7","modify_type":"I","source":"news","prepoint":"[{\"index\":\"30\",\"word\":\"广东南粤银行\"}]","groupname":"国内新闻","irhkeybbsnum":"87681672059641762220","update_time":"2022/01/17 02:06:30","pubtime":"2022/01/16 12:49:00","credit_code":"9144080019441821X1","infocategory2":"企业股份","infocategory3":"增资扩股","dwh_created_time":"2022-01-17 22:10:31.520690000","infocategory1":"公司治理"}
{"sufpoint":"[{\"index\":\"7\",\"word\":\"虚假\"},{\"index\":\"13\",\"word\":\"交易\"}]","eid":"qc188780202db93712ce68bbf018f7da4","pnum":"1","create_time":"2022/01/17 18:15:25","infoemtionlabel":"负面","entfullname":"上海屈臣氏日用品有限公司","channel":"微博","range":"8","modify_type":"I","source":"wb","prepoint":"[{\"index\":\"21\",\"word\":\"屈臣氏\"}]","groupname":"微博","irhkeybbsnum":"4726688611831505","update_time":"2022/01/17 18:15:25","pubtime":"2022/01/17 18:04:05","credit_code":"91310000607254904K","infocategory2":"运营风险","infocategory3":"财务造假","dwh_created_time":"2022-01-18 22:42:01.658617000","infocategory1":"经营管理"}

个人疑惑,根据各种资料Filter都是在Query之前的,所以我比较疑惑的是为什么方法名是.setPostFilter,而不是.setPreFilter

文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/11203
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

评论区