Elasticsearch-RestClient基础

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch-RestClient基础相关的知识,希望对你有一定的参考价值。

  • 一、认识RestClient
  • 二、使用RestClient
    1、基础准备
  • 2、RestClient操作索引库 ... ③ 编写创建索引库方法 ④ 编写删除索引库方法 ⑤ 编写判断是否存在索引库方法 3、RestClient操作文档 ① 添加文档数据方法 ② 获取文档数据方法 ③ 更新文档数据方法 ④ 删除文档数方法 ⑤ 批量操作方法


一、认识RestClient

Java REST Client (deprecated) | ElasticOverview (rest-high-level 7.12.1 API) (elastic.co)

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。

RestClient是提供给Java的客户端。


二、使用RestClient

1、基础准备

  • ① 创建表格

创建数据表​​tb_hotel​​,如下:


DROP TABLE IF EXISTS `tb_hotel`;
CREATE TABLE `tb_hotel` (
`id` bigint(20) NOT NULL COMMENT 酒店id,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 酒店名称,
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 酒店地址,
`price` int(10) NOT NULL COMMENT 酒店价格,
`score` int(2) NOT NULL COMMENT 酒店评分,
`brand` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 酒店品牌,
`city` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 所在城市,
`star_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 酒店星级,1星到5星,1钻到5钻,
`business` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 商圈,
`latitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 纬度,
`longitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 经度,
`pic` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 酒店图片,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

插入数据,如下:


INSERT INTO `tb_hotel` VALUES (36934, 7天连锁酒店(上海宝山路地铁站店), 静安交通路40号, 336, 37, 7天酒店, 上海, 二钻, 四川北路商业区, 31.251433, 121.47522, https://m.tuniucdn.com/fb2/t1/G1/M00/3E/40/Cii9EVkyLrKIXo1vAAHgrxo_pUcAALcKQLD688AAeDH564_w200_h200_c1_t0.jpg);
INSERT INTO `tb_hotel` VALUES (38609, 速8酒店(上海赤峰路店), 广灵二路126号, 249, 35, 速8, 上海, 二钻, 四川北路商业区, 31.282444, 121.479385, https://m.tuniucdn.com/fb2/t1/G2/M00/DF/96/Cii-TFkx0ImIQZeiAAITil0LM7cAALCYwKXHQ4AAhOi377_w200_h200_c1_t0.jpg);
INSERT INTO `tb_hotel` VALUES (38665, 速8酒店上海中山北路兰田路店, 兰田路38号, 226, 35, 速8, 上海, 二钻, 长风公园地区, 31.244288, 121.422419, https://m.tuniucdn.com/fb2/t1/G2/M00/EF/86/Cii-Tlk2mV2IMZ-_AAEucgG3dx4AALaawEjiycAAS6K083_w200_h200_c1_t0.jpg);
INSERT INTO `tb_hotel` VALUES (38812, 7天连锁酒店(上海漕溪路地铁站店), 徐汇龙华西路315弄58号, 298, 37, 7天酒店, 上海, 二钻, 八万人体育场地区, 31.174377, 121.442875, https://m.tuniucdn.com/fb2/t1/G2/M00/E0/0E/Cii-TlkyIr2IEWNoAAHQYv7i5CkAALD-QP2iJwAAdB6245_w200_h200_c1_t0.jpg);
INSERT INTO `tb_hotel` VALUES (39106, 7天连锁酒店(上海莘庄地铁站店), 闵行莘庄镇七莘路299号, 348, 41, 7天酒店, 上海, 二钻, 莘庄工业区, 31.113812, 121.375869, https://m.tuniucdn.com/fb2/t1/G2/M00/D8/11/Cii-T1ku2zGIGR7uAAF1NYY9clwAAKxZAHO8HgAAXVN368_w200_h200_c1_t0.jpg);
INSERT INTO `tb_hotel` VALUES (39141, 7天连锁酒店(上海五角场复旦同济大学店), 杨浦国权路315号, 349, 38, 7天酒店, 上海, 二钻, 江湾、五角场商业区, 31.290057, 121.508804, https://m.tuniucdn.com/fb2/t1/G2/M00/C7/E3/Cii-T1knFXCIJzNYAAFB8-uFNAEAAKYkQPcw1IAAUIL012_w200_h200_c1_t0.jpg);
INSERT INTO `tb_hotel` VALUES (416121, 如家酒店(北京西客站北广场店), 莲花池东路120-2号6层, 275, 43, 如家, 北京, 二钻, 北京西站/丽泽商务区, 39.896449, 116.317382, https://m.tuniucdn.com/fb3/s1/2n9c/42DTRnKbiYoiGFVzrV9ZJUxNbvRo_w200_h200_c1_t0.jpg);
  • ② 引入依赖

elasticsearch相关依赖,如下:


<!--elasticsearch-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>

因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:


<properties>
<!--指定我们所需的版本,覆盖springboot默认配置-->
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

其他依赖,如下:


<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis_plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<!--mysql_connector-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--FastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!--commons-lang3:工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
  • ③ application.yml

Ⅰ 配置服务端口;
Ⅱ 配置数据源;
Ⅲ 配置日志;
Ⅳ 配置mybatis-plus。


server:
port: 8089
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
logging:
level:
cn.test: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
type-aliases-package: cn.test.hotel.pojo
  • ④ 编写实体类

Hotel类


@Data
@TableName("tb_hotel")
public class Hotel
@TableId(type = IdType.INPUT)
private Long id;
private String name;
private String address;
private Integer price;
private Integer score;
private String brand;
private String city;
private String starName;
private String business;
private String longitude;
private String latitude;
private String pic;

HotelDoc类


@Data
@NoArgsConstructor
public class HotelDoc
private Long id;
private String name;
private String address;
private Integer price;
private Integer score;
private String brand;
private String city;
private String starName;
private String business;
private String location;
private String pic;

public HotelDoc(Hotel hotel)
this.id = hotel.getId();
this.name = hotel.getName();
this.address = hotel.getAddress();
this.price = hotel.getPrice();
this.score = hotel.getScore();
this.brand = hotel.getBrand();
this.city = hotel.getCity();
this.starName = hotel.getStarName();
this.business = hotel.getBusiness();
this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
this.pic = hotel.getPic();

geo_point类型属性映射的形式有多种,官方文档见此:Geopoint field type ,常见的形式如下图。此处我们采用第2种形式,做属性映射"location": "41.12,-71.34",所以在类型转换的时候手动拼接了属性值this.location = hotel.getLatitude() + ", " + hotel.getLongitude();

【Elasticsearch-RestClient基础】_elasticsearch


  • ⑤ 编写mapper接口及service接口&实现类


public interface HotelMapper extends BaseMapper<Hotel> 


public interface IHotelService extends IService<Hotel>


@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService

2、RestClient操作索引库

  • ① 创建索引库

Ⅰ 编写创建索引库语句:这个步骤可以在自己Dev Tools控制台内完成,然后将字段复制到IDEA。


public class HotelConstant 

public static final String MAPPING_TEMPLATE = "" +
"\\n" +
" \\"mappings\\": \\n" +
" \\"properties\\": \\n" +
" \\"id\\":\\n" +
" \\"type\\": \\"keyword\\"\\n" +
" ,\\n" +
" \\"name\\":\\n" +
" \\"type\\": \\"text\\",\\n" +
" \\"analyzer\\": \\"ik_max_word\\",\\n" +
" \\"copy_to\\": \\"all\\"\\n" +
" ,\\n" +
" \\"address\\":\\n" +
" \\"type\\": \\"keyword\\",\\n" +
" \\"index\\": false\\n" +
" ,\\n" +
" \\"price\\":\\n" +
" \\"type\\": \\"integer\\"\\n" +
" ,\\n" +
" \\"score\\":\\n" +
" \\"type\\": \\"integer\\"\\n" +
" ,\\n" +
" \\"brand\\":\\n" +
" \\"type\\": \\"keyword\\",\\n" +
" \\"copy_to\\": \\"all\\"\\n" +
" ,\\n" +
" \\"city\\":\\n" +
" \\"type\\": \\"keyword\\"\\n" +
" ,\\n" +
" \\"starName\\":\\n" +
" \\"type\\":\\"keyword\\"\\n" +
" ,\\n" +
" \\"business\\":\\n" +
" \\"type\\": \\"keyword\\",\\n" +
" \\"copy_to\\": \\"all\\"\\n" +
" ,\\n" +
" \\"location\\":\\n" +
" \\"type\\": \\"geo_point\\"\\n" +
" ,\\n" +
" \\"pic\\":\\n" +
" \\"type\\": \\"keyword\\",\\n" +
" \\"index\\": false\\n" +
" ,\\n" +
" \\"all\\":\\n" +
" \\"type\\": \\"text\\",\\n" +
" \\"analyzer\\": \\"ik_max_word\\"\\n" +
" \\n" +
" \\n" +
" \\n" +
"";

  • ② 编写测试类

​@BeforeEach​​内完成client对象的初始化配置,​​@AfterEach​​内完成操作后的资源释放。


public class HotelIndexTest 

private RestHighLevelClient client;

@BeforeEach
void setUp()
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.253.128:9200")
));


... ...

@AfterEach
void tearDown()
try
this.client.close();
catch (IOException e)
e.printStackTrace();


  • ③ 编写创建索引库方法


@Test
void createHotelIndex()
// 1. 创建Request对象
CreateIndexRequest request = new CreateIndexRequest("hotel");
// 2. 准备请求参数DSL语句
request.source(HotelConstant.MAPPING_TEMPLATE, XContentType.JSON);
// 3. 发送请求
try
client.indices().create(request, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();

【Elasticsearch-RestClient基础】_elasticsearch_02


  • ④ 编写删除索引库方法


@Test
void deleteHotelIndex()
// 1. 创建Request对象
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
// 2. 发送请求
try
client.indices().delete(request, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();

  • ⑤ 编写判断是否存在索引库方法


@Test
void existsHotelIndex()
// 1. 创建Request对象
GetIndexRequest request = new GetIndexRequest("hotel");
// 2. 发送请求
try
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.err.println(exists ? "hotel index exists!" : "hotel index not exist!");
catch (IOException e)
e.printStackTrace();


不难看出对索引库的操作有一定的相似性:
Ⅰ XXXIndexRequest:Create、Delete、Get的请求request对象;

Ⅱ client.indices().XXX():create、delete、get方法。

3、RestClient操作文档

添加@SpringBootTest注解,注入hotelService:


@Resource
private IHotelService hotelService;
  • ① 添加文档数据方法


@Test
void addDocument()
// 1. 查询数据库
Hotel hotel = hotelService.getById(36934L);
// 2. 封装成DOC对象
HotelDoc hotelDoc = new HotelDoc(hotel);
// 3. 获取request对象
IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
// 4. 将数据放入request
request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
// 5. 存储数据
try
client.index(request, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();

  • ② 获取文档数据方法


@Test
void getDocumentById()
// 1. 创建request对象
GetRequest request = new GetRequest("hotel", "36934");
try
// 2. 发送请求,得到结果
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 3. 解析结果
String json = response.getSourceAsString();

System.out.println(json);
catch (IOException e)
e.printStackTrace();

  • ③ 更新文档数据方法


@Test
void updateDocumentById()
// 1. 创建request对象
UpdateRequest request = new UpdateRequest("hotel", "36934");
// 2. 设置更新字段
request.doc(
"price", "346",
"starName", "三钻"
);
// 3. 更新文档
try
client.update(request, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();

  • ④ 删除文档数方法


@Test
void deleteDocumentById()
// 1. 创建request对象
DeleteRequest request = new DeleteRequest("hotel", "36934");
// 2. 删除文档
try
client.delete(request, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();

  • ⑤ 批量操作方法


@Test
void bulkRequest()
// 1. 获取请求对象
BulkRequest request = new BulkRequest();
// 2. 准备参数,添加多个新增的Request
// 2.1 批量获取数据库的数据
List<Hotel> hotelList = hotelService.list();
for (int i = 0; i < hotelList.size(); i++)
// 2.2 获取hotel对象
Hotel hotel = hotelList.get(i);
// 2.3 转换成hotelDoc对象
HotelDoc hotelDoc = new HotelDoc(hotel);
/*// 2.4 获取request对象
IndexRequest indexRequest = new IndexRequest("hotel").id(hotel.getId().toString());
// 2.5 将数据放入request
indexRequest.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
// 2.6 将indexRequest对象加入request
request.add(indexRequest);*/
request.add(new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc), XContentType.JSON));

// 3. 批量添加
try
client.bulk(request, RequestOptions.DEFAULT);
catch (IOException e)
e.printStackTrace();

不难看出对索引文档的操作也具有一定的相似性:

Ⅰ XXXRequest:Index、Get、Update、Delete、Bulk的请求request对象;

Ⅱ client.XXX(方法:index、get、update、delete、bulk方法。


三、结尾

以上即为RestClient基础的全部内容


线性基入门

线性基入门

简要讲解

  1. xor下的线性基:

    线性基求法:
    从高位向低位求,如果控制i位的线性基存在,则a[k]^=p[i]
    否则 p[i] = a[k];break;
    进一步,将除线性基p[i]外的线性基的i位变为0;则得到元素最小的线性基;

  2. 求第k小;
    注意当元素存在冗余,则可以异或生成0;反之,不能生成0
    将k进行2进制表示,则可对应相应的线性基进行异或

  3. 线性基的概念类似于空间张成,即通过最少的元素能张成异或运算下的整个空间

参考博客

blog1 blog2

例题HDU3949

code

#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3")
#define ll long long
#define ull unsigned long long
#define db(x) cout<<#x"=["<<(x)<<"]"<<endl
#define CL(a,b) memset(a,b,sizeof(a))
#define fast() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fr0(i,m) for(int i=0;i<m;i++)
#define fr1(i,m) for(int i=1;i<=m;i++)
//author:fridayfang
//date:19 7月 07
const double esp=1e-8;
const int mod=1e9+7;
const double pi=acos(-1);
const int inf=0x3f3f3f3f;
const int maxn = 1e4 + 5;
const int maxm = 1e6+5;
ll a[maxn];
ll p[64];
int to[100];//
ll t,n,q;
int getBase()//处理处理出线性基
    CL(p,0);//先要清0
    for(ll i=1;i<=n;i++)
        for(int j=63;j>=0;j--)
            if((a[i]>>j)&1)
                if(!p[j])p[j] = a[i]; break;
                a[i]^=p[j];
            
        
    
    // 更小的线性基
    int cnt = 0;
    for(int j=0;j<=63;j++)
        if(!p[j]) continue;
        for(int i=j+1;i<=63;i++)
            if((p[i]>>j)&1) p[i] = p[i]^p[j];
        
        to[cnt++]=j;
    
    return cnt;//cnt是线性基的个数 to[0]...to[cnt-1]有正确的映射

ll getK(ll k,int bound)//除0外的最k小
    int t = 0;
    ll tmp = k;
    ll ans = 0;
    while(tmp)
        if(t>=bound) return -1;
        if(tmp&1) ans^=p[to[t]];
        tmp = tmp>>1;
        t++;
    
    return ans;




int main()
    fast();cin>>t;
    for(ll i=1;i<=t;i++)
        cout<<"Case #"<<i<<":\\n";
        cin>>n;
        for(ll k=1;k<=n;k++) cin>>a[k];
        int cnt = getBase();
        int t = (cnt==(int)n)?0:1;//不等表示有冗余,则可表示0;此时第k小时第k-1小
        cin>>q;
        ll k;
        for(ll s=1;s<=q;s++)
            cin>>k; k-=t;
            cout<<getK(k,cnt)<<endl;
        
    

    
    return 0;

以上是关于Elasticsearch-RestClient基础的主要内容,如果未能解决你的问题,请参考以下文章

基指针中的派生对象如何调用基函数?

线性基入门

线性基讲解

肖特基二极管的作用与识别方法

线性基学习

线性基总结