Java elasticSearch

网友投稿 289 2022-10-15


Java elasticSearch

使用步骤

1.环境准备

用的是windows版,自行下载

链接: 下载地址

2.针对索引操作

这里是kibana上操作的(也可以用postman操作):

#创建索引,指定文档id

PUT /test1/type1/1

{

"name":"张三",

"age":30

}

#创建索引规则(类似数据库建表)

PUT /test2

{

"mappings": {

"properties": {

"name":{

"type":"text"

},

"age":{

"type": "integer"

},

"birthday":{

"type": "date"

}

}

}

}

#获取索引的信息,properties类型

GET test2

#创建索引,properties不指定类型会有默认类型

#也可以用作修改,但是必须写上全部字段,不然会丢失未写字段

PUT /test3/_doc/1

{

"name":"张三",

"age":30,

"birth":"1991-06-23"

}

GET test3

#查看es健康状态

GET _cat/health

#查看所有索引状态

GET _cat/indices?v

#修改

POST /test3/_doc/1/_update

{

"doc":{

"name":"李四"

}

}

3.针对doc操作(增删改)

代码如下(示例):

#新增索引,并添加doc

POST /chen/user/1

{

"name":"张三",

"age":11,

"desc":"一顿操作猛如虎,一看工资2500",

"tags":["技术宅","温暖","直男"]

}

POST /chen/user/2

{

"name":"李四",

"age":12,

"desc":"憨批",

"tags":["渣男","旅游","交友"]

}

POST /chen/user/3

{

"name":"王五",

"age":13,

"desc":"瓜怂",

"tags":["靓女","旅游","美食"]

}

POST /chen/user/4

{

"name":"刘六",

"age":14,

"desc":"锅盔",

"tags":["衰仔","旅游","美食"]

}

#获取数据

GET chen/user/1

#更新数据

POST chen/user/1/_update

{

"doc":{

"name":"更新"

}

}

#删除

DELETE chen/user/1

#条件查询,匹配度越高,_score(分值)越高

GET chen/user/_search?q=name:李

GET chen/user/_search?q=name:李四

#等价于上面

GET chen/user/_search

{

"query": {

"match": {

"name": "李四"

}

}

}

4.针对doc操作(查)

查询1(示例):

#_source结果过滤(指定需要字段结果集)

#sort排序

#from-size分页(类似limit )

#注意:这个查询是不可以些多个字段的(我试过了)

GET chen/user/_search

{

"query": {

"match": {

"name": "李四"

}

},

"_source": ["name","age"],

"sort": [

{

"age": {

"order": "asc"

}

}

],

"from":0,

"size":1

}

#多条件精确查询

#以下都是bool的二级属性

#must:必须

#should,满足任意条件

#must_not,表示不满足

GET chen/user/_search

{

"query": {

"bool": {

"must": [

{"match": {

"name": "李四"

}},

{"match": {

"age": 11

}}

]

}

}

}

#过滤.注意filter是bool(多条件)的二级属性

GET chen/user/_search

{

"query": {

"bool": {

"must": [

{"match": {

"name": "李四"

}}

],

"filter": {

"range": {

"age": {

"gte": 10,

"lte": 20

}

}

}

}

}

}

#分词器依然有效

#多个条件空格隔开就行,只要满足其中一个,就会被逮到

GET chen/user/_search

{

"query": {

"match": {

"tags": "男 技术"

}

}

}

#精确查询,结果只能为1,多条直接不显示

GET chen/user/_search

{

"query": {

"term": {

"name": "李四"

}

}

}

查询2(示例):

#新建索引

PUT test4

{

"mappings": {

"properties": {

"name":{

"type": "text"

},

"desc":{

"type": "keyword"

}

}

}

}

#插入数据

PUT test4/_doc/1

{

"name":"张三name",

"desc":"张三desc"

}

PUT test4/_doc/2

{

"name":"张三name2",

"desc":"张三desc2"

}

#分词器查询(并不是查询索引里的数据,而是将text的内容用分词器拆分的结果)

GET _analyze

{

"analyzer": "keyword",

"text": ["张三namehttp://"]

}

GET _analyze

{

"analyzer": "standard",

"text": "张三name"

}

GET test4/_search

{

"query": {

"term": {

"name": "张"

}

}

}

#==keyword不会被分词器解析==

GET test4/_search

{

"query": {

"term": {

"desc": "张三desc"

}

}

}

查询3(示例):

PUT test4/_doc/3

{

"t1":"22",

"t2":"2020-4-6"

}

PUT test4/_doc/4

{

"t1":"33",

"t2":"2020-4-7"

}

#精确查询多个值

GET test4/_search

{

"query": {

"bool": {

"should": [

{

"term": {

"t1": "22"

}

},

{

"term": {

"t1": "33"

}

}

]

}

}

}

#highlight:高亮

#pre_tags,post_tags:自定义高亮条件,前缀后缀

GET chen/user/_search

{

"query": {

"match": {

"name": "李四"

}

},

"highlight": {

"pre_tags": "

"post_tags": "

"fields": {

"name":{}

}

}

}

5.java-api

索引操作:

public class ES_Index {

private static final String HOST_NAME = "localhost";

private static final Integer PORT = 9200;

private static RestHighLevelClient client;

//创建ES客户端

static {

RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(HOST_NAME, PORT));

client = new RestHighLevelClient(restClientBuilder);

}

//关闭ES客户端

public void close() {

if (null != client) {

try {

client.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

//创建索引

public void addIndex() throws IOException {

//创建索引

CreateIndexRequest request = new CreateIndexRequest("chen");

CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);

//响应状态

System.out.println("索引创建操作: " + response.isAcknowledged());

}

//查询索引

public void selectIndex() throws IOException {

GetIndexRequest request = new GetIndexRequest("chen");

GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);

System.out.println("索引查询操作: " +response.getAliases());

System.out.println("索引查询操作: " +response.getMappings());

System.out.println("索引查询操作: " +response.getSettings());

}

//删除索引

public void deleteIndex() throws IOException {

DeleteIndexRequest request = new DeleteIndexRequest("chen");

AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);

System.out.println("索引删除操作: "+response.isAcknowledged());

}

public static void main(String[] args) throws IOException {

ES_Index index=new ES_Index();

//index.addIndex();

//index.selectIndex();

index.deleteIndex();

index.close();

}

}

文档操作:

public class ES_Doc {

private static final String HOST_NAME = "localhost";

private static final Integer PORT = 9200;

private static RestHighLevelClient client;

//创建ES客户端

static {

RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(HOST_NAME, PORT));

client = new RestHighLevelClient(restClientBuilder);

}

//关闭ES客户端

public void close() {

if (null != client) {

try {

client.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

//插入数据

public void addDoc() throws IOException {

IndexRequest request = new IndexRequest();

User user = new User("张三", "男", 18);

//向es插入数据,必须将数据转换为json格式

String userJson = new ObjectMapper().writeValueAsString(user);

request.index("user").id("1001").source(userJson, XContentType.JSON);

IndexResponse response = client.index(request, RequestOptions.DEFAULT);

System.out.println("文档创建操作: " + response.getResult());

}

//修改数据(局部修改)

public void updateDoc() throws IOException {

UpdateRequest request = new UpdateRequest();

request.index("user").id("1001").doc(XContentType.JSON, "sex", "女");

UpdateResponse response = client.update(request, RequestOptions.DEFAULT);

System.out.println("文档修改操作: " + response.getResult());

}

//获取数据

public void getDoc() throws IOException {

GetRequest request = new GetRequestNSKrug();

request.index("user").id("1001");

GetResponse response = client.get(request, RequestOptions.DEFAULT);

User user = new ObjectMapper().readValue(response.getSourceAsString(), User.class);

System.out.println("文档获取操作: " + user);

}

//删除数据

public void deleteDoc() throws IOException {

DeleteRequest request = new DeleteRequest();

request.index("user").id("1001");

DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);

System.out.println("文档删除操作: " + response.getResult());

}

//批量插入数据

public void addBatch() throws IOException {

BulkRequest request =http:// new BulkRequest();

request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "张三", "sex", "男", "age", 10));

request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "李四", "sex", "男", "age", 20));

request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "王五", "sex", "女", "age", 30));

request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "赵六", "sex", "男", "age", 40));

request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "孙七", "sex", "女", "age", 50));

BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

System.out.println("文档批量新增操作: " + response.getTook());

System.out.println("文档批量新增操作: " + !response.hasFailures());//是否失败

}

//批量删除数据

public void deleteBatch() throws IOException {

BulkRequest request = new BulkRequest();

request.add(new DeleteRequest().index("user").id("1001"));

request.add(new DeleteRequest().index("user").id("1002"));

request.add(new DeleteRequest().index("user").id("1003"));

request.add(new DeleteRequest().index("user").id("1004"));

request.add(new DeleteRequest().index("user").id("1005"));

BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

System.out.println("文档批量删除操作: " + response.getTook());

System.out.println("文档批量删除操作: " + !response.hasFailures());//是否失败

}

//查询(重点)

public void searchDoc() throws IOException {

SearchRequest request = new SearchRequest();

request.indices("user");

//1.查询索引中的全部数据

//request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));

//2.查询年龄为30的数据

//request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 30)));

//3.分页查询,当前第0页,每页两条

//request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).from(0).size(2));

//4.排序,倒序

//request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort("age", SortOrder.DESC));

//5.过滤字段(排除和包含,也可以是数组)

//request.source(new SearchSourceBuilder().fetchSource("name", null));

//6.组合查询

//BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

//6.1 must相当于and

//boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));

//boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "女"));

//6.2 should相当于or

//boolQueryBuilder.should(QueryBuilders.matchQuery("age", 30));

//boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "女"));

//request.source(new SearchSourceBuilder().query(boolQueryBuilder));

//7.范围查询

//request.source(new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").gte(30).lte(40)));

//8.模糊查询Fuzziness.ONE即只差1个字符

//request.source(new SearchSourceBuilder().query(QueryBuilders.fuzzyQuery("name", "王五").fuzziness(Fuzziness.ONE)));

//9.高亮显示

//SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchPhraseQuery("name", "张三"));

//builder.highlighter(new HighlightBuilder().preTags("").postTags("").field("name"));

//request.source(builder);

//10.聚合查询

//SearchSourceBuilder builder = new SearchSourceBuilder();

//MaxAggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");

//builder.aggregation(aggregationBuilder);

//request.source(builder);

//11.分组查询

SearchSourceBuilder builder = new SearchSourceBuilder();

TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");

builder.aggregation(aggregationBuilder);

request.source(builder);

SearchResponse response = client.search(request, RequestOptions.DEFAULT);

SearchHits hits = response.getHits();

System.out.println("--条数: " + hits.getTotalHits());

System.out.println("--用时: " + response.getTook());

hits.forEach((item)->{

System.out.println("--数据: " + item.getSourceAsString());

});

}

public static void main(String[] args) throws IOException {

ES_Doc doc = new ES_Doc();

//doc.addDoc();

//doc.updateDoc();

//doc.getDoc();

//doc.deleteDoc();

//doc.addBatch();

//doc.deleteBatch();

doc.searchDoc();

doc.close();

}

}

6.spring-data-elasticsearch

实体类: 关键在于@Document和@Field注解

shards 代表分片

replicas 代表副本

@Data

@NoArgsConstructor

@AllArgsConstructor

@Document(indexName = "product", shards = 3, replicas = 1)

public class Product {

@Id

private Long id;//商品唯一标识

@Field(type = FieldType.Text)

private String title;//商品名称

@Field(type = FieldType.Keyword)

private String category;//分类名称

@Field(type = FieldType.Double)

private Double price;//商品价格

@Field(type = FieldType.Keyword,index = false)

private String images;//图片地址

}

dao层: 这样就已经可以了,类似mybatis-plus的BaseMapper,封装好了一些操作

@Repository

public interface ProductDao extends ElasticsearchRepository {

}

yaml :不用怎么配置,默认就去找localhost:9200

测试 :不知道为啥dao的很多方法都过时了,看源码注释让回去用elasticsearchRestTemplate,感觉更繁琐

@SpringBootTest

class ElasticsearchApplicationTests {

@Autowired

ElasticsearchRestTemplate elasticsearchRestTemplate;

@Autowired

ProductDao productDao;

@Test

void createIndex() {

//创建索引,系统初始化会自动创建索引

System.out.println("创建索引");

}

@Test

void deleteIndex() {

//创建索引,系统初始化会自动创建索引

boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);

System.out.println("删除索引 = " + flg);

}

//新增数据

@Test

void addDoc() {

Product product = new Product();

product.setId(1001L);

product.setTitle("华为手机");

product.setCategory("手机");

product.setPrice(2999.0);

product.setImages("huawei.com");

productDao.save(product);

}

//修改

@Test

void updateDoc() {

Product product = new Product();

product.setId(1001L);

product.setTitle("小米手机");

product.setCategory("手机");

product.setPrice(4999.0);

product.setImages("xiaomi.com");

productDao.save(product);

}

//根据 id 查询

@Test

void findById() {

Product product = productDao.findById(1001L).get();

System.out.println(product);

}

//查询所有

@Test

void findAll() {

Iterable products = productDao.findAll();

for (Product product : products) {

System.out.println(product);

}

}

//删除

@Test

public void delete() {

productDao.deleteById(1001L);

}

//批量新增

@Test

public void saveAll() {

List productList = new ArrayList<>();

for (int i = 0; i < 10; i++) {

Product product = new Product();

product.setId((long) i);

product.setTitle("[" + i + "]小米手机");

product.setCategory("手机");

product.setPrice(1999.0 + i);

product.setImages("http://atguigu/xm.jpg");

productList.add(product);

}

productDao.saveAll(productList);

}

//分页查询

@Test

void findByPageable() {

Sort orders = Sort.by(Sort.Direction.DESC, "id");

Pageable pageable = PageRequest.of(0, 5, orders);

Page products = productDao.findAll(pageable);

products.forEach(System.out::println);

}

/**

* term 查询

* search(termQueryBuilder) 调用搜索方法,参数查询构建器对象

*/

@Test

void termQuery() {

TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");

Iterable products = productDao.search(termQueryBuilder);

products.forEach(System.out::println);

}

/**

* term 查询加分页

*/

@Test

void termQueryByPage() {

PageRequest pageRequest = PageRequest.of(0, 5);

TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");

Iterable products = productDao.search(termQueryBuilder, pageRequest);

products.forEach(System.out::println);

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:TCP/IP协议栈
下一篇:聚焦链改,双卡双待
相关文章

 发表评论

暂时没有评论,来抢沙发吧~