springboot中es的使用与学习
在java中使用es的一些基本操作
·
在java中使用es的一些基本操作,干货满满,记得点赞哦!
引入与配置
我这里不写关于 es的部署,如果要看es的部署,请移步 ~
首先在springboot项目的pom文件中引入需要的包
<!-- ES搜索 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.5.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.4</version>
</dependency>
这里呢
不建议引用最新的包,
至于原因嘛,有很多,例如,我的jdk还是1.8。
第二步也很简单,配置文件的配置
我用的是yml,只说yml。
spring:
#指明es服务器地址
elasticsearch:
rest:
uris: http://103.59.148.103:9200
username: hehe
password: *********
下面,进入重点课程,es的java使用。
实体类的构建
/**
* @Author: zhaoz
* @CreateTime: 2022年11月11日
* @Description: ES 数据结构
*/
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "test_console")
@Accessors(chain = true)
@Data
public class InfoEntity implements Serializable {
private static final long serialVersionUID = -2942121322430364691L;
@Id
@ApiModelProperty("id")
private String id;
@ApiModelProperty("info时间")
@Field(name = "info_time", type = FieldType.Date, format = {}, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime infoTime;
@ApiModelProperty("标题")
@Field(name = "title", type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@ApiModelProperty("内容")
@Field(name = "content", type = FieldType.Text, analyzer = "ik_max_word")
private String content;
@ApiModelProperty("地址")
@Field(name = "address", type = FieldType.Text, analyzer = "ik_max_word")
private String address;
}
index索引:es的索引的添加
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@PostMapping("/createdIndex2")
@ApiOperation(value = "学习创建索引")
public String createdIndex2(@RequestParam("index") String index) {
// 判断索引是否存在
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(index).local(false).humanReadable(true);
if (client.indices().exists(getIndexRequest, RequestOptions.DEFAULT)) {
return "存在索引!";
} else {
// 设置settings映射
Settings settings = Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0).build();
// 设置mapping映射
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
// keyId
.startObject("id").field("type", "long").endObject()
// title
.startObject("info_title").field("type", "keyword").endObject()
// content
.startObject("info_content").field("type", "text").endObject()
// birthday
.startObject("info_time")
.field("type", "date")
.field("format", "yyyy-MM-dd HH:mm:ss")
.field("ignore_malformed", true).endObject()
// address
.startObject("address").field("type", "text").endObject()
.endObject().endObject();
boolean createIndexResponse = getCreateIndexResponse(new CreateIndexRequest(index).settings(settings).mapping(mapping));
if (createIndexResponse) {
return "创建索引成功";
} else {
return "创建索引失败";
}
}
} catch (Exception e) {
e.printStackTrace();
return e.getLocalizedMessage();
}
}
private boolean getCreateIndexResponse(CreateIndexRequest createIndexRequest) throws Exception {
String index = createIndexRequest.index();
try {
// 超时时间设置为 1m
createIndexRequest.setTimeout(TimeValue.timeValueMinutes(1));
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
if (createIndexResponse.isAcknowledged()) {
// 创建ES索引成功
return true;
} else {
// 创建ES索引失败
return false;
}
} catch (Exception e) {
throw new Exception("创建ES索引[" + index + "]异常", e);
}
}
index索引: ES索引的删除
删除索引 会删除数据
/**
* 删除索引 会删除数据
* @param index
* @return
*/
@DeleteMapping("/deleteIndex")
@ApiOperation(value = "学习删除索引")
public String deleteIndex(@RequestParam("index") String index) {
// 判断索引是否存在
try {
GetIndexRequest getIndexRequest = new GetIndexRequest(index).local(false).humanReadable(true);
if (client.indices().exists(getIndexRequest, RequestOptions.DEFAULT)) {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);
deleteIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
AcknowledgedResponse acknowledgedResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
if (acknowledgedResponse.isAcknowledged()) {
return "删除索引成功";
} else {
return "删除索引失败";
}
} else {
return "索引不存在!";
}
} catch (Exception e) {
e.printStackTrace();
return e.getLocalizedMessage();
}
}
添加es索引内容
@PostMapping("/addESFieldContent")
@ApiOperation(value = "添加字段内容(map格式)")
public R addESFieldContent(@RequestBody Map<String, String> maps) throws IOException {
// 可以使用Map作为参数
IndexRequest indexRequest = new IndexRequest();
indexRequest.index(INDEXES_TYPE);
indexRequest.source(maps);
// 可以使用XConttentBuilder构建内容
// XContentBuilder builder = XContentFactory.jsonBuilder();
// builder.startObject();
// {
// builder.field("user", "kimchy");
// builder.timeField("postDate", new Date());
// builder.field("message", "trying out Elasticsearch");
// }
// builder.endObject();
// IndexRequest indexRequest = new IndexRequest("posts")
// .id("1").source(builder);
// 发送请求到ES
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
return R.ok(response);
}
还有一种,就需要用到我们创建好的实体类InfoEntity
- 创建接口InfoRepository继承ElasticsearchRepository
package com.whisper.db.esRepository;
import com.whisper.db.domain.InfoEntity;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface InfoRepository extends ElasticsearchRepository<InfoEntity, String> {
}
- 引用并实现新增(save)、批量新增(saveAll);
@Autowired
private InfoRepository infoRepository;
@PostMapping("/addESContent")
@ApiOperation(value = "保存es内容")
public R addESContent(@RequestBody InfoEntity entity) throws Exception {
InfoEntity save = infoRepository.save(entity);
return R.ok(save);
}
查询es索引下所有数据
@GetMapping("/match/all")
@ApiOperation(value = "学习数据查询")
public String matchAll(@RequestParam("index") String index) throws IOException {
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
//2.指明使用matchall查询
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchAllQuery());
// 查询条数
builder.size(10);
request.source(builder);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.输出
return response.toString();
}
es 对新增索引内容的修改
这里我只写一种我们可能会经常用到的修改方式;
@PutMapping("/editESFieldContent")
@ApiOperation(value = "修改字段内容")
public R editFieldContent(@RequestBody Map<String, String> maps) throws IOException {
// 这是我前面创建的索引,记得替换成自己的
String index = "test_console";
UpdateRequest update = new UpdateRequest();
update.index(index).id(maps.get("id"));
// 拓展:局部更新可以这样写:update.doc(XContentType.JSON, "name", "李四", "age", 25);,其中"name"和"age"是User对象中的字段名称,而"小美"和25是对应的字段值
update.doc(XContentType.JSON, "info_title", maps.get("title"), "info_content", maps.get("content"));
// 全部更新需要重新传入数据
// update.doc(JSONObject.toJSONString(maps), XContentType.JSON);
// 3、发送请求到ES
UpdateResponse response = client.update(update, RequestOptions.DEFAULT);
return R.ok(response);
}
这里需要注意 map里面的id是es生成的id
再附上一个有用的es 语句。
POST /test_console/_doc/LWNgf4QBMMqlRJmSXSlf/_update
{
"doc":{
"info_title": "外交部发言人回应达苏恐袭案宣判:这是对正义的伸张、对遇难中国同胞的告慰。"
}
}
es 搜索 条件检索内容(激动人心的时刻就在这里)
- 最简单的es模糊查询(单字段匹配)
@GetMapping("/match/search")
@ApiOperation(value = "es模糊搜索")
public String matchSearch(
@RequestParam("index") String index,
@RequestParam("keyword") String keyword) throws IOException {
if (StringUtils.isEmpty(keyword)) {
return "";
}
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
//2.指明使用match查询
SearchSourceBuilder builder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("info_content", keyword);
builder.query(matchQueryBuilder);
builder.size(10);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return response.toString();
}
- 查询不同字段内的关键字内容
多字段检索,是组合查询的另一种形态,如果考察多字段检索,并不一定必须使用multi_match,也可以使用bool query
@GetMapping("/multiMatch/search")
@ApiOperation(value = "es模糊搜索")
public String multiMatch(
@RequestParam("index") String index,
@RequestParam("keyword") String keyword) throws IOException {
if (StringUtils.isEmpty(keyword)) {
return "";
}
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
//2.指明使用match查询
String[] fieldNames = {"info_content", "info_title"};
SearchSourceBuilder builder = new SearchSourceBuilder();
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, fieldNames);
builder.query(multiMatchQueryBuilder);
builder.size(10);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return response.toString();
}
- 查询不同字段内关键字(完整关键字,不分词)
multi_match type:- best_fields:侧重于字段维度,单个字段的得分权重大,对于同一个 query,单个field匹配更多的term,则优先排序。
- most_fields:侧重于查询维度,单个查询条件的得分权重大,如果一次请求中,对于同一个doc,匹配到某个term的field越多,则越优先排序。
- cross_fields:对于一些实体,标识信息会在多个字段中出现,每个字段中只含有一部分信息。
- phrase_prefix:等同于 最左前缀查询。
- phrase: 等同于 短语查询
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, fieldNames).type("phrase");
这里使用的也比较简单 就是.type(“phrase”)
4. 查询不同字段不同关键字的查询
这里使用的是 es 查询语句的 bool query
需要注意的是 must、和 should的区别。
// 附上 es的语法,更清晰的明白Java的写法。
GET /test_console/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "宙斯盾号军舰89",
"fields": ["info_content","info_title"],
"type": "phrase"
}
},
{
"multi_match": {
"query": "空军",
"fields": ["info_content","info_title"],
"type": "phrase"
}
}
]
}
},
"from": 0,
"size": "20"
}
@GetMapping("/match/bool/multiQuery")
@ApiOperation(value = "es模糊搜索")
public R matchBoolPhraseQuery(@Param("index") String index,
@Param("fields") String fields,
@Param("keywords") String keywords) throws IOException {
// String index = "test_console";
SearchRequest request = new SearchRequest(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
if (StringUtils.isEmpty(keywords)) {
builder.query(QueryBuilders.matchAllQuery());
builder.size(10);
} else {
String[] keywordg = keywords.split(" ");
//2.指明使用match查询
String[] fieldNames = {};
if (StringUtils.isNotEmpty(fields)) {
fieldNames = fields.split(" ");
} else {
fieldNames = new String[]{"news_content", "news_title"};
}
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
for (String keyword:keywordg) {
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword, fieldNames).type("phrase"));
}
builder.query(boolQueryBuilder);
builder.size(10);
}
request.source(builder);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 结果解析
SearchHits hits = response.getHits();
List<Map<String, Object>> results = new ArrayList<>();
for (SearchHit documentFields : hits.getHits()) {
Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
results.add(sourceAsMap);
}
return R.ok(results);
}
继续学习中。。。
敬请期待 ~
更多推荐
已为社区贡献2条内容
所有评论(0)