代码地址
1.document
1.pom
代码语言:xml复制<dependencies>
<!--es客户端-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<!-- low:偏向底层。high :高級封装。足够。-->
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.3.0</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>2.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
2.yaml
代码语言:yaml复制spring:
application:
name: search-service
kwan:
elasticsearch:
hostlist: 47.119.162.180:9200 #多个节点用逗号分隔
3.config
代码语言:java复制@Configuration
public class ElasticsearchConfig {
@Value("${kwan.elasticsearch.hostlist}")
private String hostlist;
@Bean(destroyMethod = "close")
public RestHighLevelClient restHighLevelClient() {
String[] split = hostlist.split(",");
HttpHost[] httpHostsArray = new HttpHost[split.length];
for (int i = 0; i < split.length; i ) {
String item = split[i];
httpHostsArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
}
return new RestHighLevelClient(RestClient.builder(httpHostsArray));
}
}
4.get
代码语言:java复制@Slf4j
@SpringBootTest(classes = SearchApplication.class)
@RunWith(SpringRunner.class)
public class TestDocument_01_get {
@Autowired
RestHighLevelClient client;
@Test
public void testGet() throws IOException {
//构建请求
GetRequest getRequest = new GetRequest("test_post", "1");
//添加可选参数
String[] includes = new String[]{"id", "comment"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
getRequest.fetchSourceContext(fetchSourceContext);
//同步查询
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
//获取结果
if (getResponse.isExists()) {
log.info(getResponse.getId());
log.info(String.valueOf(getResponse.getVersion()));
log.info(getResponse.getSourceAsString());//以string获取数据
log.info(String.valueOf(getResponse.getSourceAsBytes()));////以Bytes获取数据
log.info(String.valueOf(getResponse.getSourceAsMap()));//以Map获取数据
} else {
log.info("数据不存在");
}
}
}
代码语言:java复制@Test
public void testGet() {
//构建请求
GetRequest getRequest = new GetRequest("test_post", "1");
//添加可选参数
String[] includes = new String[]{"id", "title"};
String[] excludes = Strings.EMPTY_ARRAY;
FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
getRequest.fetchSourceContext(fetchSourceContext);
//设置监听器
ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
//成功时
public void onResponse(GetResponse getResponse) {
log.info(getResponse.getId());
log.info(String.valueOf(getResponse.getVersion()));
log.info(getResponse.getSourceAsString());
}
//失败时
public void onFailure(Exception e) {
e.printStackTrace();
log.info("数据获取异常");
}
};
//异步查询
client.getAsync(getRequest, RequestOptions.DEFAULT, listener);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
5.add
代码语言:java复制@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("5");
//构建文档数据
String jsonString = "{n"
" "user":"tomas",n"
" "postDate":"2019-07-18",n"
" "message":"trying out es1"n"
"}";
request.source(jsonString, XContentType.JSON);
//同步
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" result);
} else {
log.info("其他操作");
}
//获取分片信息
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
代码语言:java复制 @Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("6");
//构建文档数据
Map<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("user", "tomas");
jsonMap.put("postDate", "2019-07-18");
jsonMap.put("message", "trying out es1");
request.source(jsonMap);
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
代码语言:java复制@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("7");
//构建文档数据
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.field("user", "tomas");
builder.field("message", "trying out es1");
builder.timeField("postDate", "2019-07-18");
}
builder.endObject();
request.source(builder);
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
代码语言:java复制@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("9");
//构建文档数据
request.source("user", "tomas",
"message", "trying out es1",
"postDate", "2019-07-18");
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
代码语言:java复制@Test
public void testAdd() throws IOException {
//构建请求
IndexRequest request = new IndexRequest("test_post");
request.id("10");
//构建文档数据
String jsonString = "{n"
" "user":"tomas",n"
" "postDate":"2019-07-18",n"
" "message":"trying out es1"n"
"}";
request.source(jsonString, XContentType.JSON);
//设置超时时间
request.timeout("1s");
request.timeout(TimeValue.timeValueSeconds(1));
//手动维护版本号
request.version(4);
request.versionType(VersionType.EXTERNAL);
//同步执行
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
//获取结果
log.info(indexResponse.getIndex());
log.info(indexResponse.getId());
log.info(String.valueOf(indexResponse.getResult()));
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("CREATE" result);
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = indexResponse.getResult();
log.info("UPDATED" result);
}
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
log.info("处理成功的分片数少于总分片!");
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();//每一个错误的原因
log.info(reason);
}
}
}
6.update
代码语言:java复制@Test
public void testUpdate() throws IOException {
//创建请求
UpdateRequest request = new UpdateRequest("test_post", "5");
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("user", "tomas Lee");
request.doc(jsonMap);
request.timeout("1s");
request.retryOnConflict(3);//重试次数
//同步执行
UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
//获取结果
updateResponse.getId();
updateResponse.getIndex();
//判断结果
if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
DocWriteResponse.Result result = updateResponse.getResult();
log.info("CREATED:" result);
} else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
DocWriteResponse.Result result = updateResponse.getResult();
log.info("UPDATED:" result);
} else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
DocWriteResponse.Result result = updateResponse.getResult();
log.info("DELETED:" result);
} else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
//没有操作
DocWriteResponse.Result result = updateResponse.getResult();
log.info("NOOP:" result);
}
}
7.delete
代码语言:java复制@Test
public void testDelete() throws IOException {
//创建请求
DeleteRequest request = new DeleteRequest("test_post", "3");
//执行
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
//获取结果
deleteResponse.getId();
deleteResponse.getIndex();
DocWriteResponse.Result result = deleteResponse.getResult();
log.info(result.toString());
}
8.bulk
代码语言:java复制@Test
public void testBulk() throws IOException {
//创建请求
BulkRequest request = new BulkRequest();
request.add(new IndexRequest("post").id("1").source(XContentType.JSON, "field", "1"));
request.add(new IndexRequest("post").id("2").source(XContentType.JSON, "field", "2"));
request.add(new UpdateRequest("post", "1").doc(XContentType.JSON, "field", "3"));
request.add(new DeleteRequest("post").id("2"));
//执行
BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
//获取结果
for (BulkItemResponse itemResponse : bulkResponse) {
DocWriteResponse response = itemResponse.getResponse();
switch (itemResponse.getOpType()) {
case INDEX:
IndexResponse indexResponse = (IndexResponse) response;
log.info("INDEX:" indexResponse.getResult());
break;
case CREATE:
IndexResponse createResponse = (IndexResponse) response;
log.info("CREATE:" createResponse.getResult());
break;
case UPDATE:
UpdateResponse updateResponse = (UpdateResponse) response;
log.info("UPDATE:" updateResponse.getResult());
break;
case DELETE:
DeleteResponse deleteResponse = (DeleteResponse) response;
log.info("DELETE:" deleteResponse.getResult());
break;
}
}
}
2.index
1.创建索引
代码语言:java复制@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex_01_Create {
@Autowired
private RestHighLevelClient client;
//创建索引
@Test
public void testCreateIndex() throws IOException {
// PUT /my_index
// {
// "settings": {
// "number_of_shards": 1,
// "number_of_replicas": 1
// },
// "mappings": {
// "properties": {
// "field1":{
// "type": "text"
// },
// "field2":{
// "type": "text"
// }
// }
// },
// "aliases": {
// "default_index": {}
// }
// }
//创建索引对象
CreateIndexRequest createIndexRequest = new CreateIndexRequest("itheima_book");
//设置参数
createIndexRequest.settings(Settings.builder().put("number_of_shards", "1").put("number_of_replicas", "0"));
//指定映射1
createIndexRequest.mapping(" {n"
" t"properties": {n"
" "name":{n"
" "type":"keyword"n"
" },n"
" "description": {n"
" "type": "text"n"
" },n"
" "price":{n"
" "type":"long"n"
" },n"
" "pic":{n"
" "type":"text",n"
" "index":falsen"
" }n"
" t}n"
"}", XContentType.JSON);
//设置别名
createIndexRequest.alias(new Alias("itheima_index_new"));
// 额外参数
//设置超时时间
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(2));
//设置主节点超时时间
createIndexRequest.setMasterTimeout(TimeValue.timeValueMinutes(1));
//在创建索引API返回响应之前等待的活动分片副本的数量,以int形式表示
createIndexRequest.waitForActiveShards(ActiveShardCount.from(2));
createIndexRequest.waitForActiveShards(ActiveShardCount.DEFAULT);
//操作索引的客户端
IndicesClient indices = client.indices();
//执行创建索引库
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
//得到响应
boolean acknowledged = createIndexResponse.isAcknowledged();
//得到响应 指示是否在超时前为索引中的每个分片启动了所需数量的碎片副本
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();
System.out.println("acknowledged:" acknowledged);
System.out.println("shardsAcknowledged:" shardsAcknowledged);
}
}
代码语言:java复制@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex_04_Async {
@Autowired
private RestHighLevelClient client;
//创建索引异步方式
@Test
public void testCreateIndexAsync() {
//创建索引对象
CreateIndexRequest createIndexRequest = new CreateIndexRequest("itheima_book");
//设置参数
createIndexRequest.settings(Settings.builder().put("number_of_shards", "1").put("number_of_replicas", "0"));
//指定映射1
createIndexRequest.mapping(" {n"
" t"properties": {n"
" "name":{n"
" "type":"keyword"n"
" },n"
" "description": {n"
" "type": "text"n"
" },n"
" "price":{n"
" "type":"long"n"
" },n"
" "pic":{n"
" "type":"text",n"
" "index":falsen"
" }n"
" t}n"
"}", XContentType.JSON);
//设置别名
createIndexRequest.alias(new Alias("itheima_index_new"));
// 额外参数
//设置超时时间
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(2));
//设置主节点超时时间
createIndexRequest.setMasterTimeout(TimeValue.timeValueMinutes(1));
//在创建索引API返回响应之前等待的活动分片副本的数量,以int形式表示
createIndexRequest.waitForActiveShards(ActiveShardCount.from(2));
createIndexRequest.waitForActiveShards(ActiveShardCount.DEFAULT);
//操作索引的客户端
IndicesClient indices = client.indices();
//执行创建索引库
ActionListener<CreateIndexResponse> listener = new ActionListener<CreateIndexResponse>() {
@Override
public void onResponse(CreateIndexResponse createIndexResponse) {
//得到响应(全部)
boolean acknowledged = createIndexResponse.isAcknowledged();
//得到响应 指示是否在超时前为索引中的每个分片启动了所需数量的碎片副本
boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();
System.out.println("acknowledged:" acknowledged);
System.out.println("shardsAcknowledged:" shardsAcknowledged);
}
@Override
public void onFailure(Exception e) {
e.printStackTrace();
}
};
client.indices().createAsync(createIndexRequest, RequestOptions.DEFAULT, listener);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.删除索引
代码语言:java复制@Test
public void testDeleteIndex() throws IOException {
//创建删除索引请求
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("itheima_book");
// 执行
AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
//得到相应
boolean acknowledged = delete.isAcknowledged();
System.out.println("acknowledged:" acknowledged);
}
3.是否存在索引
代码语言:java复制 @Test
public void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("itheima_book");
//参数
request.local(false);//从主节点返回本地索引信息状态
request.humanReadable(true);//以适合人类的格式返回
request.includeDefaults(false);//是否返回每个索引的所有默认配置
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println("exists:" exists);
}
4.关闭索引
代码语言:java复制@Test
public void testCloseIndex() throws IOException {
CloseIndexRequest request = new CloseIndexRequest("itheima_book");
AcknowledgedResponse close = client.indices().close(request, RequestOptions.DEFAULT);
boolean acknowledged = close.isAcknowledged();
System.out.println("acknowledged:" acknowledged);
}
5.打开索引
代码语言:java复制@Test
public void testOpenIndex() throws IOException {
OpenIndexRequest request = new OpenIndexRequest("itheima_book");
OpenIndexResponse open = client.indices().open(request, RequestOptions.DEFAULT);
boolean acknowledged = open.isAcknowledged();
System.out.println("acknowledged:" acknowledged);
}
3.search
1.all
代码语言:java复制@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSearch_01_all {
@Autowired
RestHighLevelClient client;
@Test
public void testSearchAll() throws IOException {
// GET book/_search
// {
// "query": {
// "match_all": {}
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//获取某些字段
searchSourceBuilder.fetchSource(new String[]{"name"}, new String[]{});
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("score:" score);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
}
2.page
代码语言:java复制@Test
public void testSearchPage() throws IOException {
// GET book/_search
// {
// "query": {
// "match_all": {}
// },
// "from": 0,
// "size": 2
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//第几页
int page = 1;
//每页几个
int size = 2;
//下标计算
int from = (page - 1) * size;
searchSourceBuilder.from(from);
searchSourceBuilder.size(size);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
3.ids
代码语言:java复制@Test
public void testSearchIds() throws IOException {
// GET /book/_search
// {
// "query": {
// "ids" : {
// "values" : ["1", "4", "100"]
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.idsQuery().addIds("1", "4", "100"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
4.match
代码语言:java复制@Test
public void testSearchMatch() throws IOException {
// GET /book/_search
// {
// "query": {
// "match": {
// "description": "java程序员"
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("description", "java程序员"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
5.term
代码语言:java复制@Test
public void testSearchTerm() throws IOException {
//
// GET /book/_search
// {
// "query": {
// "term": {
// "description": "java程序员"
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("description", "java程序员"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
6.multi_match
代码语言:java复制@Test
public void testSearchMultiMatch() throws IOException {
// GET /book/_search
// {
// "query": {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name", "description"]
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("java程序员", "name", "description"));
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
7.bool
代码语言:java复制 @Test
public void testSearchBool() throws IOException {
// GET /book/_search
// {
// "query": {
// "bool": {
// "must": [
// {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name","description"]
// }
// }
// ],
// "should": [
// {
// "match": {
// "studymodel": "201001"
// }
// }
// ]
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建multiMatch请求
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("java程序员", "name", "description");
//构建match请求
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.should(matchQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
8.filter
代码语言:java复制@Test
public void testSearchFilter() throws IOException {
// GET /book/_search
// {
// "query": {
// "bool": {
// "must": [
// {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name","description"]
// }
// }
// ],
// "should": [
// {
// "match": {
// "studymodel": "201001"
// }
// }
// ],
// "filter": {
// "range": {
// "price": {
// "gte": 50,
// "lte": 90
// }
// }
//
// }
// }
// }
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建multiMatch请求
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("java程序员", "name", "description");
//构建match请求
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.should(matchQueryBuilder);
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(50).lte(90));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
9.sort
代码语言:java复制@Test
public void testSearchSort() throws IOException {
// GET /book/_search
// {
// "query": {
// "bool": {
// "must": [
// {
// "multi_match": {
// "query": "java程序员",
// "fields": ["name","description"]
// }
// }
// ],
// "should": [
// {
// "match": {
// "studymodel": "201001"
// }
// }
// ],
// "filter": {
// "range": {
// "price": {
// "gte": 50,
// "lte": 90
// }
// }
//
// }
// }
// },
// "sort": [
// {
// "price": {
// "order": "asc"
// }
// }
// ]
// }
//1构建搜索请求
SearchRequest searchRequest = new SearchRequest("book");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构建multiMatch请求
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("java程序员", "name", "description");
//构建match请求
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.should(matchQueryBuilder);
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(50).lte(90));
searchSourceBuilder.query(boolQueryBuilder);
//按照价格升序
searchSourceBuilder.sort("price", SortOrder.ASC);
searchRequest.source(searchSourceBuilder);
//2执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//3获取结果
SearchHits hits = searchResponse.getHits();
//数据数据
SearchHit[] searchHits = hits.getHits();
System.out.println("--------------------------");
for (SearchHit hit : searchHits) {
String id = hit.getId();
float score = hit.getScore();
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
String description = (String) sourceAsMap.get("description");
Double price = (Double) sourceAsMap.get("price");
System.out.println("id:" id);
System.out.println("name:" name);
System.out.println("description:" description);
System.out.println("price:" price);
System.out.println("==========================");
}
}
4.sql 功能
前提 es 拥有白金版功能:
kibana 中管理-》许可管理 开启白金版试用
导入依赖:
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>x-pack-sql-jdbc</artifactId>
<version>7.3.0</version>
</dependency>
<repositories>
<repository>
<id>elastic.co</id>
<url>https://artifacts.elastic.co/maven</url>
</repository>
</repositories>
代码:
public class TestJdbc {
public static void main(String[] args) {
//1创建连接
try {
Connection connection = DriverManager.getConnection("jdbc:es://http://localhost:9200");
//2创建statement
Statement statement = connection.createStatement();
//3执行sql语句
ResultSet resultSet = statement.executeQuery("SELECT * FROM tvs");
//4获取结果
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
System.out.println(resultSet.getString(4));
System.out.println("======================================");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5.学成在线站内搜索模块
1.mysql 导入学生数据
代码语言:mysql复制/*
Navicat Premium Data Transfer
Source Server : local
Source Server Type : MySQL
Source Server Version : 50721
Source Host : localhost:3306
Source Schema : xc_course
Target Server Type : MySQL
Target Server Version : 50721
File Encoding : 65001
Date: 10/11/2019 02:50:34
*/
SET
NAMES utf8mb4;
SET
FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for course_pub
-- ----------------------------
DROP TABLE IF EXISTS `course_pub`;
CREATE TABLE `course_pub` (
`id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键',
`name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程名称',
`users` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '适用人群',
`mt` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '大分类',
`st` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '小分类',
`grade` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程等级',
`studymodel` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '学习模式',
`teachmode` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '教育模式',
`description` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程介绍',
`timestamp` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '时间戳logstash使用',
`charge` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '收费规则,对应数据字典',
`valid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '有效性,对应数据字典',
`qq` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '咨询qq',
`price` float(10, 2) NULL DEFAULT NULL COMMENT '价格',
`price_old` float(10, 2) NULL DEFAULT NULL COMMENT '原价格',
`expires` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '过期时间',
`start_time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程有效期-开始时间',
`end_time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程有效期-结束时间',
`pic` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程图片',
`teachplan` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程计划',
`pub_time` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '发布时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of course_pub
-- ----------------------------
INSERT INTO
`course_pub`
VALUES
(
'297e7c7c62b888f00162b8a7dec20000',
'test_java基础33',
'b1',
'1-3',
'1-3-3',
'200002',
'201002',
NULL,
'java 从入门到删库跑路',
'2019-10-28 11:26:25',
'203002',
'204002',
'32432',
NULL,
NULL,
NULL,
NULL,
NULL,
'group1/M00/00/00/wKgZhV2tIgiAaYVMAAA2T52Dthw246.jpg',
'{"children":[{"children":[],"id":"40288f9b6e0c10d8016e0c37f72a0000","pname":"1"},{"children":[{"id":"40288581632b593e01632bd53ff10001","mediaFileoriginalname":"solr.avi","mediaId":"5fbb79a2016c0eb609ecd0cd3dc48016","pname":"Hello World"},{"id":"40288f9b6e106273016e106485f30000","mediaFileoriginalname":"lucene.avi","mediaId":"c5c75d70f382e6016d2f506d134eee11","pname":"java基础"}],"id":"40288581632b593e01632bd4ec360000","pname":"程序入门"},{"children":[{"id":"40288f9b6dce18e3016dcef16d860001","mediaFileoriginalname":"solr.avi","mediaId":"5fbb79a2016c0eb609ecd0cd3dc48016","pname":"三级节点"}],"id":"40288f9b6dce18e3016dcef12a1d0000","pname":"二级节点"},{"children":[{"id":"40288c9a6ca3968e016ca417fa8d0001","mediaFileoriginalname":"lucene.avi","mediaId":"c5c75d70f382e6016d2f506d134eee11","pname":"test04-01"}],"id":"40288c9a6ca3968e016ca417b4a50000","pname":"test04"},{"children":[{"id":"40288581632b593e01632bd5d31f0003","mediaFileoriginalname":"solr.avi","mediaId":"5fbb79a2016c0eb609ecd0cd3dc48016","pname":"表达式"},{"id":"40288581632b593e01632bd606480004","pname":"逻辑运算"}],"id":"40288581632b593e01632bd597810002","pname":"编程基础"},{"children":[{"id":"402881e764034e4301640351f3d70003","pname":"一切皆为对象"}],"id":"402881e764034e430164035091a00002","pname":"面向对象"},{"children":[{"id":"402899816ad8457c016ad9282a330001","pname":"test06"}],"id":"402899816ad8457c016ad927ba540000","pname":"test05"}],"id":"4028858162bec7f30162becad8590000","pname":"test_java基础33"}',
'2019-10-28 11:26:24'
);
INSERT INTO
`course_pub`
VALUES
(
'297e7c7c62b888f00162b8a965510001',
'test_java基础node',
'test_java基础',
'1-3',
'1-3-2',
'200001',
'201001',
NULL,
'test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2test_java基础2',
'2019-10-24 16:26:34',
'203001',
'204001',
'443242',
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
'{"children":[{"children":[{"id":"402881e66417407b01641744fc650001","pname":"入门程序"}],"id":"402881e66417407b01641744afc30000","pname":"基础知识"},{"children":[],"id":"4028858162e5d6e00162e5e0727d0001","pname":"java基础语法"},{"children":[{"id":"4028d0866b158241016b502433d60002","pname":"第二节"}],"id":"4028d0866b158241016b5023f51e0001","pname":"第二章"}],"id":"4028858162e5d6e00162e5e0227b0000","pname":"test_java基础2"}',
'2019-10-24 16:26:33'
);
SET
FOREIGN_KEY_CHECKS = 1;
2.创建索引 xc_course
3.创建映射
代码语言:apl复制PUT /xc_course
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"description" : {
"analyzer" : "ik_max_word",
"search_analyzer": "ik_smart",
"type" : "text"
},
"grade" : {
"type" : "keyword"
},
"id" : {
"type" : "keyword"
},
"mt" : {
"type" : "keyword"
},
"name" : {
"analyzer" : "ik_max_word",
"search_analyzer": "ik_smart",
"type" : "text"
},
"users" : {
"index" : false,
"type" : "text"
},
"charge" : {
"type" : "keyword"
},
"valid" : {
"type" : "keyword"
},
"pic" : {
"index" : false,
"type" : "keyword"
},
"qq" : {
"index" : false,
"type" : "keyword"
},
"price" : {
"type" : "float"
},
"price_old" : {
"type" : "float"
},
"st" : {
"type" : "keyword"
},
"status" : {
"type" : "keyword"
},
"studymodel" : {
"type" : "keyword"
},
"teachmode" : {
"type" : "keyword"
},
"teachplan" : {
"analyzer" : "ik_max_word",
"search_analyzer": "ik_smart",
"type" : "text"
},
"expires" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"pub_time" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"start_time" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"end_time" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
4.logstash 创建模板文件
Logstash 的工作是从 MySQL 中读取数据,向 ES 中创建索引,这里需要提前创建 mapping 的模板文件以便 logstash 使用。
在 logstach 的 config 目录创建 xc_course_template.json,内容如下:
代码语言:json复制{
"mappings": {
"doc": {
"properties": {
"charge": {
"type": "keyword"
},
"description": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"type": "text"
},
"end_time": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"expires": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"grade": {
"type": "keyword"
},
"id": {
"type": "keyword"
},
"mt": {
"type": "keyword"
},
"name": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"type": "text"
},
"pic": {
"index": false,
"type": "keyword"
},
"price": {
"type": "float"
},
"price_old": {
"type": "float"
},
"pub_time": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"qq": {
"index": false,
"type": "keyword"
},
"st": {
"type": "keyword"
},
"start_time": {
"format": "yyyy-MM-dd HH:mm:ss",
"type": "date"
},
"status": {
"type": "keyword"
},
"studymodel": {
"type": "keyword"
},
"teachmode": {
"type": "keyword"
},
"teachplan": {
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart",
"type": "text"
},
"users": {
"index": false,
"type": "text"
},
"valid": {
"type": "keyword"
}
}
}
},
"template": "xc_course"
}
5.logstash 配置 mysql.conf
ES 采用 UTC 时区问题
ES 采用 UTC 时区,比北京时间早 8 小时,所以 ES 读取数据时让最后更新时间加 8 小时
where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)
logstash 每个执行完成会在/config/logstash_metadata 记录执行时间下次以此时间为基准进行增量同步数据到索引库。
6.启动
代码语言:apl复制.logstash.bat -f ..configmysql.conf
7.后端代码
代码地址
7.1.Controller
代码语言:java复制@RestController
@RequestMapping("/search/course")
public class EsCourseController {
@Autowired
private EsCourseServiceImpl esCourseServiceImpl;
@GetMapping(value = "/list/{page}/{size}")
public QueryResponseResult<CoursePub> list(@PathVariable("page") int page
, @PathVariable("size") int size, CourseSearchParam courseSearchParam) {
return esCourseServiceImpl.list(page, size, courseSearchParam);
}
}