首页 > 滚动 > > 内容页

【ES三周年】万字长文带你实战 Elasticsearch 搜索

2023-02-26 16:17:00 腾讯云

ES 高级实战

前言

上篇我们讲到了 Elasticsearch 全文检索的原理《别只会搜日志了,求你懂点原理吧》,通过在本地搭建一套 ES 服务,以多个案例来分析了 ES 的原理以及基础使用。这次我们来讲下 Spring Boot 中如何整合 ES,以及如何在 Spring Cloud 微服务项目中使用 ES 来实现全文检索,来达到搜索题库的功能。

而且题库的数据量是非常大的,题目的答案也是非常长的,通过 ES 正好可以解决 mysql 模糊搜索的低效性。


(资料图片)

通过本实战您可以学到如下知识点:

Spring Boot 如何整合 ES。微服务中 ES 的 API 使用。项目中如何使用 ES 来达到全文检索。

本篇主要内容如下:

主要内容

本文案例都是基于 PassJava 实战项目来演示的。

:+1:Github 地址:https://github.com/Jackson0714/PassJava-Platform

一、Elasticsearch 组件库介绍

在讲解之前,我在这里再次提下全文检索是什么:

全文检索:指以全部文本信息作为检索对象的一种信息检索技术。而我们使用的数据库,如 Mysql,MongoDB 对文本信息检索能力特别是中文检索并没有 ES 强大。所以我们来看下 ES 在项目中是如何来代替 SQL 来工作的。

我使用的 Elasticsearch 服务是 7.4.2 的版本,然后采用官方提供的 Elastiscsearch-Rest-Client 库来操作 ES,而且官方库的 API 上手简单。

该组件库的官方文档地址:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

另外这个组件库是支持多种语言的:

支持多语言

注意:Elasticsearch Clients就是指如何用 API 操作 ES 服务的组件库。

可能有同学会提问,Elasticsearch 的组件库中写着 JavaScript API,是不是可以直接在前端访问 ES 服务?可以是可以,但是会暴露 ES 服务的端口和 IP 地址,会非常不安全。所以我们还是用后端服务来访问 ES 服务。

我们这个项目是 Java 项目,自然就是用上面的两种:Java Rest Client或者 Java API。我们先看下 Java API,但是会发现已经废弃了。如下图所示:

Java API 已经废弃了

所以我们只能用 Java REST Client 了。而它又分成两种:高级和低级的。高级包含更多的功能,如果把高级比作MyBatis的话,那么低级就相当于JDBC。所以我们用高级的 Client。

高级和低级 Client

二、整合检索服务

我们把检索服务单独作为一个服务。就称作 passjava-search 模块吧。

1.1 添加搜索服务模块

创建 passjava-search 模块。

首先我们在 PassJava-Platform 模块创建一个 搜索服务模块 passjava-search。然后勾选 spring web 服务。如下图所示。

第一步:选择 Spring Initializr,然后点击 Next。

选择 Spring Initializr

第二步:填写模块信息,然后点击 Next。

passjava-search 服务模块

第三步:选择 Web->Spring Web 依赖,然后点击 Next。

mark

1.2 配置 Maven 依赖

参照 ES 官网配置。

进入到 ES 官方网站,可以看到有低级和高级的 Rest Client,我们选择高阶的(High Level Rest Client)。然后进入到高阶 Rest Client 的 Maven 仓库。官网地址如下所示:

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.9/index.html
Rest Client 官方文档
加上 Maven 依赖。

对应文件路径:\passjava-search\pom.xml

    org.elasticsearch.client    elasticsearch-rest-high-level-client    7.4.2
配置 elasticsearch 的版本为7.4.2

因加上 Maven 依赖后,elasticsearch 版本为 7.6.2,所以遇到这种版本不一致的情况时,需要手动改掉。

对应文件路径:\passjava-search\pom.xml

7.4.2

刷新 Maven Project 后,可以看到引入的 elasticsearch 都是 7.4.2 版本了,如下图所示:

设置版本为 7.4.2
引入 PassJava 的 Common 模块依赖。

Common 模块是 PassJava 项目独立的出来的公共模块,引入了很多公共组件依赖,其他模块引入 Common 模块依赖后,就不需要单独引入这些公共组件了,非常方便。

对应文件路径:\passjava-search\pom.xml

     com.jackson0714.passjava     passjava-common     0.0.1-SNAPSHOT

添加完依赖后,我们就可以将搜索服务注册到 Nacos注册中心了。 Nacos 注册中心的用法在前面几篇文章中也详细讲解过,这里需要注意的是要先启动 Nacos 注册中心,才能正常注册 passjava-search 服务。

1.3 注册搜索服务到注册中心

修改配置文件:src/main/resources/application.properties。配置应用程序名、注册中心地址、注册中心的命名中间。

spring.application.name=passjava-searchspring.cloud.nacos.config.server-addr=127.0.0.1:8848spring.cloud.nacos.config.namespace=passjava-search

启动类添加服务发现注解:@EnableDiscoveryClient。这样 passjava-search 服务就可以被注册中心发现了。

因 Common 模块依赖数据源,但 search 模块不依赖数据源,所以 search 模块需要移除数据源依赖:

exclude = DataSourceAutoConfiguration.class

以上的两个注解如下所示:

@EnableDiscoveryClient@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)public class PassjavaSearchApplication {    public static void main(String[] args) {        SpringApplication.run(PassjavaSearchApplication.class, args);    }}

接下来我们添加一个 ES 服务的专属配置类,主要目的是自动加载一个 ES Client 来供后续 ES API 使用,不用每次都 new 一个 ES Client。

1.4 添加 ES 配置类

配置类:PassJavaElasticsearchConfig.java

核心方法就是 RestClient.builder 方法,设置好 ES 服务的 IP 地址、端口号、传输协议就可以了。最后自动加载了 RestHighLevelClient。

package com.jackson0714.passjava.search.config;import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @Author: 公众号 | 悟空聊架构 * @Date: 2020/10/8 17:02 * @Site: www.passjava.cn * @Github: https://github.com/Jackson0714/PassJava-Platform */@Configurationpublic class PassJavaElasticsearchConfig {    @Bean    // 给容器注册一个 RestHighLevelClient,用来操作 ES    // 参考官方文档:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.9/java-rest-high-getting-started-initialization.html    public RestHighLevelClient restHighLevelClient() {        return new RestHighLevelClient(                RestClient.builder(                        new HttpHost("192.168.56.10", 9200, "http")));    }}

接下来我们测试下 ES Client 是否自动加载成功。

1.5 测试 ES Client 自动加载

在测试类 PassjavaSearchApplicationTests 中编写测试方法,打印出自动加载的 ES Client。期望结果是一个 RestHighLevelClient 对象。

package com.jackson0714.passjava.search;import org.elasticsearch.client.RestHighLevelClient;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.boot.test.context.SpringBootTest;@SpringBootTestclass PassjavaSearchApplicationTests {    @Qualifier("restHighLevelClient")    @Autowired    private RestHighLevelClient client;    @Test    public void contextLoads() {        System.out.println(client);    }}

运行结果如下所示,打印出了 RestHighLevelClient。说明自定义的 ES Client 自动装载成功。

ES 测试结果

1.6 测试 ES 简单插入数据

测试方法 testIndexData,省略 User 类。users 索引在我的 ES 中是没有记录的,所以期望结果是 ES 中新增了一条 users 数据。

/** * 测试存储数据到 ES。 * */@Testpublic void testIndexData() throws IOException {    IndexRequest request = new IndexRequest("users");    request.id("1"); // 文档的 id        //构造 User 对象    User user = new User();    user.setUserName("PassJava");    user.setAge("18");    user.setGender("Man");        //User 对象转为 JSON 数据    String jsonString = JSON.toJSONString(user);        // JSON 数据放入 request 中    request.source(jsonString, XContentType.JSON);    // 执行插入操作    IndexResponse response = client.index(request, RequestOptions.DEFAULT);    System.out.println(response);}

执行 test 方法,我们可以看到控制台输出以下结果,说明数据插入到 ES 成功。另外需要注意的是结果中的 result 字段为 updated,是因为我本地为了截图,多执行了几次插入操作,但因为 id = 1,所以做的都是 updated 操作,而不是 created 操作。

控制台输出结果

我们再来到 ES 中看下 users 索引中数据。查询 users 索引:

GET users/_search

结果如下所示:

查询 users 索引结果

可以从图中看到有一条记录被查询出来,查询出来的数据的 _id = 1,和插入的文档 id 一致。另外几个字段的值也是一致的。说明插入的数据没有问题。

"age" : "18","gender" : "Man","userName" : "PassJava"

1.7 测试 ES 查询复杂语句

示例:搜索 bank 索引,address 字段中包含 big 的所有人的年龄分布 ( 前 10 条 ) 以及平均年龄,以及平均薪资。

1.7.1 构造检索条件

我们可以参照官方文档给出的示例来创建一个 SearchRequest 对象,指定要查询的索引为 bank,然后创建一个 SearchSourceBuilder 来组装查询条件。总共有三种条件需要组装:

address 中包含 road 的所有人。按照年龄分布进行聚合。计算平均薪资。

代码如下所示,需要源码请到我的 Github/PassJava 上下载。

查询复杂语句示例

将打印出来的检索参数复制出来,然后放到 JSON 格式化工具中格式化一下,再粘贴到 ES 控制台执行,发现执行结果是正确的。

打印出检索参数

用在线工具格式化 JSON 字符串,结果如下所示:

格式化 JSON 字符串

然后我们去掉其中的一些默认参数,最后简化后的检索参数放到 Kibana 中执行。

Kibana Dev Tools 控制台中执行检索语句如下图所示,检索结果如下图所示:

控制台中执行检索语句

找到总记录数:29 条。

第一条命中记录的详情如下:

平均 balance:13136。

平均年龄:26。

地址中包含 Road 的:263 Aviation Road。

和 IDEA 中执行的测试结果一致,说明复杂检索的功能已经成功实现。

17.2 获取命中记录的详情

而获取命中记录的详情数据,则需要通过两次 getHists() 方法拿到,如下所示:

// 3.1)获取查到的数据。SearchHits hits = response.getHits();// 3.2)获取真正命中的结果SearchHit[] searchHits = hits.getHits();

我们可以通过遍历 searchHits 的方式打印出所有命中结果的详情。

// 3.3)、遍历命中结果for (SearchHit hit: searchHits) {    String hitStr = hit.getSourceAsString();    BankMember bankMember = JSON.parseObject(hitStr, BankMember.class);}

拿到每条记录的 hitStr 是个 JSON 数据,如下所示:

{"account_number": 431,"balance": 13136,"firstname": "Laurie","lastname": "Shaw","age": 26,"gender": "F","address": "263 Aviation Road","employer": "Zillanet","email": "laurieshaw@zillanet.com","city": "Harmon","state": "WV"}

而 BankMember 是根据返回的结果详情定义的的 JavaBean。可以通过工具自动生成。在线生成 JavaBean 的网站如下:

https://www.bejson.com/json2javapojo/new/

把这个 JavaBean 加到 PassjavaSearchApplicationTests 类中:

@ToString@Datastatic class BankMember {    private int account_number;    private int balance;    private String firstname;    private String lastname;    private int age;    private String gender;    private String address;    private String employer;    private String email;    private String city;    private String state;}

然后将 bankMember 打印出来:

System.out.println(bankMember);
bankMember

得到的结果确实是我们封装的 BankMember 对象,而且里面的属性值也都拿到了。

1.7.3 获取年龄分布聚合信息

ES 返回的 response 中,年龄分布的数据是按照 ES 的格式返回的,如果想按照我们自己的格式来返回,就需要将 response 进行处理。

如下图所示,这个是查询到的年龄分布结果,我们需要将其中某些字段取出来,比如 buckets,它代表了分布在 21 岁的有 4 个。

ES 返回的年龄分布信息

下面是代码实现:

Aggregations aggregations = response.getAggregations();Terms ageAgg1 = aggregations.get("ageAgg");for (Terms.Bucket bucket : ageAgg1.getBuckets()) {    String keyAsString = bucket.getKeyAsString();    System.out.println("用户年龄: " + keyAsString + " 人数:" + bucket.getDocCount());}

最后打印的结果如下,21 岁的有 4 人,26 岁的有 4 人,等等。

打印结果:用户年龄分布

1.7.4 获取平均薪资聚合信息

现在来看看平均薪资如何按照所需的格式返回,ES 返回的结果如下图所示,我们需要获取 balanceAvg 字段的 value 值。

ES 返回的平均薪资信息

代码实现:

Avg balanceAvg1 = aggregations.get("balanceAvg");System.out.println("平均薪资:" + balanceAvg1.getValue());

打印结果如下,平均薪资 28578 元。

打印结果:平均薪资

三、实战:同步 ES 数据

3.1 定义检索模型

PassJava 这个项目可以用来配置题库,如果我们想通过关键字来搜索题库,该怎么做呢?

类似于百度搜索,输入几个关键字就可以搜到关联的结果,我们这个功能也是类似,通过 Elasticsearch 做检索引擎,后台管理界面和小程序作为搜索入口,只需要在小程序上输入关键字,就可以检索相关的题目和答案。

首先我们需要把题目和答案保存到 ES 中,在存之前,第一步是定义索引的模型,如下所示,模型中有 titleanswer字段,表示题目和答案。

"id": {    "type": "long"},"title": {    "type": "text",    "analyzer": "ik_smart"},"answer": {    "type": "text",    "analyzer": "ik_smart"},"typeName": {    "type": "keyword"}

3.2 在 ES 中创建索引

上面我们已经定义了索引结构,接着就是在 ES 中创建索引。

在 Kibana 控制台中执行以下语句:

PUT question{"mappings" : {    "properties": {  "id": {  "type": "long"  },  "title": {  "type": "text",  "analyzer": "ik_smart"  },  "answer": {  "type": "text",  "analyzer": "ik_smart"  },  "typeName": {  "type": "keyword"  }}  }}

执行结果如下所示:

创建 question 索引

我们可以通过以下命令来查看 question 索引是否在 ES 中:

GET _cat/indices

执行结果如下图所示:

查看 ES 中所有的索引

3.3 定义 ES model

上面我们定义 ES 的索引,接着就是定义索引对应的模型,将数据存到这个模型中,然后再存到 ES 中。

ES 模型如下,共四个字段:id、title、answer、typeName。和 ES 索引是相互对应的。

@Datapublic class QuestionEsModel {    private Long id;    private String title;    private String answer;    private String typeName;}

3.4 触发保存的时机

当我们在后台创建题目或保存题目时,先将数据保存到 mysql 数据库,然后再保存到 ES 中。

如下图所示,在管理后台创建题目时,触发保存数据到 ES 。

mark

第一步,保存数据到 mysql 中,项目中已经包含此功能,就不再讲解了,直接进入第二步:保存数据到 ES 中。

而保存数据到 ES 中,需要将数据组装成 ES 索引对应的数据,所以我用了一个 ES model,先将数据保存到 ES model 中。

3.5 用 model 来组装数据

这里的关键代码时 copyProperties,可以将 question对象的数据取出,然后赋值到 ES model 中。不过 ES model 中还有些字段是 question 中没有的,所以需要单独拎出来赋值,比如 typeName 字段,question 对象中没有这个字段,它对应的字段是 question.type,所以我们把 type 取出来赋值到 ES model 的 typeName 字段上。如下图所示:

用 model 来组装数据

3.6 保存数据到 ES

我在 passjava-search 微服务中写了一个保存题目的 api 用来保存数据到 ES 中。

保存数据到 ES

然后在 passjava-question 微服务中调用 search 微服务的保存 ES 的方法就可以了。

// 调用 passjava-search 服务,将数据发送到 ES 中保存。searchFeignService.saveQuestion(esModel);

3.7 检验 ES 中是否创建成功

我们可以通过 kibana 的控制台来查看 question 索引中的文档。通过以下命令来查看:

GET question/_search

执行结果如下图所示,有一条记录:

mark

另外大家有没有疑问:可以重复更新题目吗?

答案是可以的,保存到 ES 的数据是幂等的,因为保存的时候带了一个类似数据库主键的 id。

四、实战:查询 ES 数据

我们已经将数据同步到了 ES 中,现在就是前端怎么去查询 ES 数据中,这里我们还是使用 Postman 来模拟前端查询请求。

4.1 定义请求参数

请求参数我定义了三个:

keyword:用来匹配问题或者答案。id:用来匹配题目 id。pageNum:用来分页查询数据。

这里我将这三个参数定义为一个类:

@Datapublic class SearchParam {    private String keyword; // 全文匹配的关键字    private String id; // 题目 id    private Integer pageNum; // 查询第几页数据}

4.2 定义返回参数

返回的 response 我也定义了四个字段:

questionList:查询到的题目列表。pageNum:第几页数据。total:查询到的总条数。totalPages:总页数。

定义的类如下所示:

@Datapublic class SearchQuestionResponse {    private List questionList; // 题目列表    private Integer pageNum; // 查询第几页数据    private Long total; // 总条数    private Integer totalPages; // 总页数}

4.3 组装 ES 查询参数

调用 ES 的查询 API 时,需要构建查询参数。

组装查询参数的核心代码如下所示:

组装查询参数
第一步:创建检索请求。第二步:设置哪些字段需要模糊匹配。这里有三个字段:title,answer,typeName。第三步:设置如何分页。这里分页大小是 5 个。第四步:调用查询 api。

4.4 格式化 ES 返回结果

ES 返回的数据是 ES 定义的格式,真正的数据被嵌套在 ES 的 response 中,所以需要格式化返回的数据。

核心代码如下图所示:

格式化 ES 返回结果
第一步:获取查到的数据。第二步:获取真正命中的结果。第三步:格式化返回的数据。第四步:组装分页参数。

4.5 测试 ES 查询

4.5.1 实验一:测试 title 匹配

我们现在想要验证 title 字段是否能匹配到,传的请求参数 keyword = 111,匹配到了 title = 111 的数据,且只有一条。页码 pageNum 我传的 1,表示返回第一页数据。如下图所示:

测试匹配 title

4.5.2 实验二:测试 answer 匹配

我们现在想要验证 answer 字段是否能匹配到,传的请求参数 keyword = 测试答案,匹配到了 title = 测试答案的数据,且只有一条,说明查询成功。如下图所示:

测试匹配 answer

4.5.2 实验三:测试 id 匹配

我们现在想要匹配题目 id 的话,需要传请求参数 id,而且 id 是精确匹配。另外 id 和 keyword 是取并集,所以不能传 keyword 字段。

请求参数 id = 5,返回结果也是 id =5 的数据,说明查询成功。如下图所示:

测试 id 匹配

五、总结

本文通过我的开源项目 passjava 来讲解 ES 的整合,ES 的 API 使用以及测试。非常详细地讲解了每一步该如何做,相信通过阅读本篇后,再加上自己的实践,一定能掌握前后端该如何使用 ES 来达到高效搜索的目的。

当然,ES API 还有很多功能未在本文实践,有兴趣的同学可以到 ES 官网进行查阅和学习。

x 广告
最近更新

【ES三周年】万字长文带你实战 Elasticsearch 搜索

2023-02-26

每日聚焦:东肌科

2023-02-26

100复仇之门21_100复仇之门全通关图文攻略第17关

2023-02-26

环球观速讯丨中医防治慢性病系列:癌症

2023-02-26

最资讯丨重庆推出25条扶持政策加速制造业数字化转型

2023-02-26

刘嘉玲:过生日时,戴了一顶镶满钻石的皇冠,在香港能换10座豪宅|今日快看

2023-02-26

环球时讯:中国土系志:吉林卷

2023-02-26

点亮心灵的灯_作文

2023-02-26

今日热文:北京密云区太师屯镇总工会举办专场招聘会

2023-02-25

巴陵石化

2023-02-25

北京现代ix35如何自己更换大灯灯泡 每日视点

2023-02-25

女神吧

2023-02-25

智商税什么意思_智商

2023-02-25

2023年钢市,或将没有“金三银四”|全球消息

2023-02-25

世纪花园酒店

2023-02-25

河北4人入选2022“中国非遗年度人物”100人候选名单

2023-02-25

易筋经十二式呼吸法视频_易筋经十二式呼吸法-焦点速讯

2023-02-25

非法占有的认定_非法占有

2023-02-24

Spiral

2023-02-24

长春市实验_关于长春市实验的介绍

2023-02-24

椰视频丨爆炸连连,海口这个饭店老板多次逆行灭火

2023-02-24

二次批价 当前快播

2023-02-24

复制全选快捷键是什么_快捷键是什么|环球热议

2023-02-24

河北税务:便民办税送“春风” 营商环境培“沃土”

2023-02-24

辉煌科技:公司董事长一直以来正常履职并主持相关工作-热资讯

2023-02-24

天天讯息:04月03日宁波前往铜川出行防疫轨迹疫情政策汇总

2023-02-24

比亚迪车主诉惊魂一幕:最后50公里续航迅速归零

2023-02-24

经济稳定与增长职能_稳定经济增长职能的内容主要包括哪些-天天热推荐

2023-02-24

快看:翡翠和玉是一样的吗

2023-02-23

天天速读:市政府工作组已进驻商丘公交公司具体详细内容是什么

2023-02-23

商务部:《中国禁止出口限制出口技术目录》已结束公开征求意见的工作 简讯

2023-02-23

新一代广汽本田雅阁或于二季度上市 内饰与海外版居然“大不同”!-全球今亮点

2023-02-23

四川雅安:规范企业用工 维护快递员合法权益_环球时快讯

2023-02-23

西安脑康心理医院:孩子不愿意去上学我们可以做些什么 每日热闻

2023-02-23

x战警天启彩蛋,x战警逆转未来彩蛋里那个年轻的天启是谁扮演的

2023-02-23

宅家像度假!128㎡简约风大平层,住起来别提多惬意! 焦点报道

2023-02-23

全球焦点!荣耀智能手表GS Pro通过优化获得新的固件更新

2023-02-23

防控阻击战还是狙击战_阻击战和狙击战的区别

2023-02-23

天天观焦点:大梅沙攻略_游玩攻略详解

2023-02-22

全球快播:动态投资回收期和静态投资回收期的区别_动态投资回收期

2023-02-22

四川金顶: 四川金顶关于公司2023年度向特定对象发行A股股票发行方案的论证分析报告的事前认可意见 快看

2023-02-22

突发!大巴黎最新决定遭质疑,梅西遭重大打击,内马尔姆巴佩很意外

2023-02-22

cad打印戳记怎么去掉_cad打印怎么把教育版去掉|天天新视野

2023-02-22

长沙城乡居民养老保险参保办理条件

2023-02-22

新消息丨山东老字号|周村烧饼:脱胎于千年前胡饼的中华名吃

2023-02-22

焦点关注:南亚新材(688519)2月21日主力资金净卖出36.49万元

2023-02-22

欧盟重要听证会前微软“服软”:为保690亿美元收购暴雪,“愿化解担忧”-天天热门

2023-02-22

世界新消息丨如何做美甲_如何做美甲不会掉

2023-02-21

以下哪种饮品的热量更高 蚂蚁庄园今日答案7月26日

2023-02-21

足协6人被抓后,风暴刮向裁判界,曝马宁帮陈戌源吹假哨,将被拷

2023-02-21

环球今头条!万亿宁王专利诉讼“再下一城”!这家动力电池巨头:上诉!

2023-02-21

新婚祝贺的诗_新婚贺语诗句 每日看点

2023-02-21

世界今日报丨明日天气早知道

2023-02-21

西峡法院:谎报财产被发现 当场划扣没商量

2023-02-21

烧心导致的咳嗽和气喘容易诱发哮喘这是因为胃酸刺激胸腔神经 天天速看料

2023-02-21

波兰当地时间2月20日宣布进一步限制与白俄罗斯之间的陆路交通|全球关注

2023-02-21

个人所得税年终奖金计算器_新个人所得税年终奖金

2023-02-21

未来几天,定南这些地方要停电,请相互转告!

2023-02-20

环球聚焦:access数据库入门教程之操作界面_access数据库入门教程

2023-02-20

资讯:央行5年期以上LPR4.3%,惠州最低房贷利率3.8%

2023-02-20

最新资讯:申城“梅”景全面上线 奉上梅花观赏点位 | 组图

2023-02-20

江苏省委巡视组组长是什么级别_省委巡视组组长是什么级别

2023-02-20

天天最新:道明证券:料新西兰联储本周加息50个基点

2023-02-20

菜的组词二年级下册_菜的组词

2023-02-20

氖读音_氖|环球快播

2023-02-20

姆巴佩已在法甲打入149球,在联赛历史射手榜排名第20位

2023-02-19

龙迅股份:2月21日在上交所上市,股票代码688486-环球关注

2023-02-19

天天新资讯:如何粘合 CPVC 管

2023-02-19

头条焦点:如何连接组合插座开关

2023-02-19

处暑节气含义_处暑节气介绍

2023-02-19

环球今日讯!广州音籁音响设备有限公司

2023-02-19

昕锐用什么型号的机油_科鲁兹用什么型号机油|天天视点

2023-02-19

世界快资讯丨能源互联网技术创新加快推动构建新型电力系统

2023-02-18

世界视点!如何剥章鱼皮

2023-02-18

奥马哈牛排烹饪指南

2023-02-18

昆明市矣六街道新亚洲体育城社区:党建“绣花针”穿动社区治理千条线

2023-02-18

最新消息:如何制作蜜饯山核桃

2023-02-18

02月18日06时青海海南州疫情数据 阳了以后为什么会腰疼?应该怎么办?-天天滚动

2023-02-18

广州阿里通云仓物流有限公司

2023-02-18

今日店铺转让怎么发朋友圈吸引人_店铺转让怎么写吸引人

2023-02-17

【天天新要闻】眉山东坡区:打好便企利企“组合拳” 跑出不动产登记“加速度”

2023-02-17

让美看清现实?2600多万吨原油成功抵达中国,美元时代或将终结|焦点

2023-02-17

环球微资讯!聚酯纤维是啥面料和纯棉哪个好_聚酯纤维100%对人体有害吗

2023-02-17

保存为自定义用户设置是什么意思_设置保存成功

2023-02-17

快报:阴虚内热怎么调理_阴虚内热怎么调理

2023-02-17

中国电信副总经理李峻:
云网融合助力千兆城市建设数智赋能引领城市治理未来 速讯

2023-02-17

每日看点!海棠区生活垃圾分类督导检查工作日报2023年2月15日

2023-02-17

AptarGroup(ATR.US):2022年Q4财报实现营收7.959亿美元 当前热门

2023-02-17

今年经开区固定资产投资超千亿

2023-02-17

魅族16s_关于魅族16s的介绍 天天热头条

2023-02-16

当前速讯:重庆计算机等级考试报名(时间+入口+缴费)

2023-02-16

参观南京梅花山买什么门票_环球热点

2023-02-16

一天世界让子弹飞 据说牛市慢涨急跌 全球讯息

2023-02-16

2023苏州姑苏景点医护人员免费指南_天天最新

2023-02-16

每日讯息!02月16日09时陕西榆林疫情数据 阳了以后为什么会腰疼?应该怎么办?

2023-02-16

一立方米等于多少立方分米_世界关注

2023-02-16

足协发布官方消息强调未审核通过的俱乐部需要针对性调整_当前速读

2023-02-16

全球球精选!怎么更换电脑IP地址_怎么更改ip地址

2023-02-16

太湖大道一路好风景

2023-02-16

2022年5月26日五行穿衣指南,五行旺运幸运颜色搭配分享 天天快消息

2023-02-16

李幼斌个人简历资料介绍_和前妻张瑞琪为什么离婚

2023-02-16

宁夏贺兰苏峪口瓷窑遗址揭示全新窑业类型

2023-02-16

全球视讯!7月21日是什么日子(节日、纪念日)

2023-02-15

女性意识觉醒的现实意义_女性意识_全球快讯

2023-02-15

企业计提员工代扣款项时会计分录怎么写-焦点消息

2023-02-15

中国农业大学有哪些专业 列出如下25个专业

2023-02-15

支付宝nft是什么意思 环球快报

2023-02-15

迪阿股份跌4.5% IPO超募32亿上市即巅峰中信建投保荐 天天看点

2023-02-15

世界实时:怎么更新电脑网卡驱动 电脑网卡驱动更新的方法 一起来看看

2023-02-15

【世界聚看点】焦作解放法院执行工作暖人心 申请执行人与被执行人“双双送锦旗”

2023-02-15

清代瓷器“堂名款”资料丨收藏版

2023-02-15

富士康年终奖有多少 年终奖竟然这么少|当前热点

2023-02-15

新华社:甘肃山地马拉松4大疑问待解 到底是天灾还是人祸

2023-02-15

环球速看:第一星运 2023年水瓶座3月运势

2023-02-15

阳了应该怎么办-阳性感染者如何用药 02月15日06时广东阳江疫情数据

2023-02-15

《红星照耀中国》读后感5篇感悟

2023-02-15

天天热推荐:苹果为USB-C 转 MagSafe 3 连接线(2 米)发布固件更新 10M1543

2023-02-15

【天天快播报】入党申请书的正确格式范文_优秀的入党申请书模板

2023-02-15

【网言】大可不必担心《水浒传》会把孩子教坏 天天报资讯

2023-02-15

当前头条:鸠占鹊巢的意思是什么

2023-02-15

《宝可梦:朱紫》太晶坑各BOSS打法一览[多图]-环球观速讯

2023-02-14

科学美容护肤小常识有哪些 热点评

2023-02-14

每日消息!彻底白热化!美媒预测赛季6大奖:威少超六,字母恩比德无缘MVP

2023-02-14

当前热文:金庸群侠传3加强版门派攻略_金庸群侠传3加强版攻略少林

2023-02-14

天天快播:《大国工匠》观后感

2023-02-14

利尔达:公司股票将于2月17日在北交所上市 全球最新

2023-02-14

天天百事通!轻质碳酸钾商品报价动态(2023-02-14)

2023-02-14

低俗玩家渗入多款游戏?女网友发声:不希望游戏沦为“交友软件” 全球球精选

2023-02-14

历年英语六级考试写作

2023-02-14

新款225 kW JCW GP成为SA最昂贵的Mini 世界微动态

2023-02-14

焦点速讯:厦门信达:厦门信达中天网络科技有限公司主要从事互联网信息服务等业务

2023-02-14

西藏持续提升农牧区供水保障能力_每日观点

2023-02-14

全球讯息:n86诺基亚软件_n86诺基亚

2023-02-14

“23洛建02”2月14日起在上交所挂牌

2023-02-14

世界百事通!油条面放冰箱的目的

2023-02-14

送礼送什么好

2023-02-13

每日讯息!53719是什么意思

2023-02-13

国家能源局:2022年中国电力市场交易规模和主体数量均创历史新高 短讯

2023-02-13

中国医药:目前互联网渠道无法购买新冠口服药Paxlovid

2023-02-13

提前锁定!厦门市文化影视产业新政策线上宣讲2月14日开播

2023-02-13

东安动力首台混动纵置前驱DHT点火成功

2023-02-13

当前滚动:中国维和多功能工兵分队出色完成“猛虎

2023-02-13

天津成立特殊教育资源中心-世界热消息

2023-02-13

全球速讯:02月13日06时湖南岳阳疫情数据 阳了以后为什么会腰疼?应该怎么办?

2023-02-13

热推荐:2022年度中国杠杆率报告:资产负债表“躺平”与宏观杠杆率攀升的迷思

2023-02-13

焦点快看:金彭贝:不会为与拜仁一战而担忧 巴黎并非是姆巴佩一个人的球队

2023-02-12

全球滚动:法国举行第四次跨行业罢工游行 反对退休制度改革

2023-02-12

送女生的生日礼物排行榜

2023-02-12

硅料之王的春天来了

2023-02-11

当前热讯:贵德县农业水价综合改革工作成功入选全国典型经验

2023-02-11

《热线》回复|县人民医院上线|当前报道

2023-02-11

女高中同桌过生日送什么礼物

2023-02-11

深市主板首份2022年年报出炉 美利云去年实现营收11亿元

2023-02-11

大连市气象局发布大风蓝色预警【IV级/一般】 环球动态

2023-02-11

大眼贼虾百科_大眼贼日本沼虾 焦点速读

2023-02-11

如何追男生 女生倒追男生的6种方法 天天即时

2023-02-11

天天播报:腐殖酸

2023-02-11

电脑没声音是什么问题_电脑没声音是什么原因|热消息

2023-02-10

环球视讯!为偷电动三轮将自己的车留下,民警“守株待兔”等小偷儿

2023-02-10

微信公众号推广的方法是什么?|当前观点

2023-02-10

给巨蟹座送礼物|环球快资讯

2023-02-10

碧聊语音聊天关闭了_碧聊语音聊天室|快报

2023-02-10

环球微资讯!养殖鸭的成本与利润计算方法(养鸭10000只鸭利润和成本)

2023-02-10

速读:茅山道长2电视剧全集_茅山道长电视剧全集

2023-02-10

【天天播资讯】墨西哥央行连续第14次加息

2023-02-10

摔角动态离开后 战神高柏回归泰拳训练_当前视点

2023-02-10

三星8552是什么型号_三星8552参数|重点聚焦

2023-02-10

晨会博弈:北向资金净买入再度超120亿 市场重回上升趋势? 今日精选

2023-02-10

冲浪宜居网上楼市官网_淮安网上楼市

2023-02-10

河南省灵宝市发布大雾橙色预警

2023-02-10

ipad画画软件procreate教程 全球快报

2023-02-10

天天热文:二女儿送美丽鲜花

2023-02-10

北京地铁6号线首末车时间表2020-世界简讯

2023-02-10

总体施工组织布置及规划公路工程-总体施工组织布置及规划

2023-02-10

环球头条:山东省电视台生活帮电话号码_山东电视台生活帮热线

2023-02-09

止步两连降!1月网约车订单量环比升14.1% 环球今日讯

2023-02-09

2020年12生肖运势解析 2020年12生肖运势解析完整版

2023-02-09

天天播报:2月9日成都新房成交508套,二手房897套

2023-02-09

世界速递!安吉又赢麻了!威少剩1620万薪水 爵士7年内15首轮+今夏6千万空间

2023-02-09

当前快看:大众高尔夫W12概念车身转换高尔夫V

2023-02-09

韩彩英主演的电视剧_关于韩彩英主演的电视剧的介绍

2023-02-09

全球最资讯丨简笔画q版人物萌图片_画q版人物萌图片

2023-02-09

环球观焦点:乘风破浪的姐姐们首播时间 乘风破浪的姐姐们首播时间是2020年6月12日

2023-02-09

《金枝(全本)》:中原大地上的家族史诗

2023-02-09

烟头温度可达多少度它超过了棉麻毛织物-全球要闻

2023-02-09

山东省委省政府通报表扬!这些文艺工作先进单位在列_当前快播

2023-02-09

2020年高速公路免费时间 高速公路免费到几号?_环球百事通

2023-02-09

苗疆道事·第十一卷·风云年代_关于苗疆道事·第十一卷·风云年代的简介

2023-02-09

今日讯!月工作总结格式模板(十篇)2022

2023-02-09

苗疆_关于苗疆的简介-全球微资讯

2023-02-09

江西东乡:制订“用电效能建议书”为企业生产助力

2023-02-09

吃甲鱼要注意什么 天天快资讯

2023-02-08

新动态:centrum

2023-02-08

爱上不该爱的人伤感文章3篇

2023-02-08

世界百事通!全年发放政府消费券1100万元!双鸭山发布重磅“23条”

2023-02-08

中国交建:第四季度单季新签合同额为5101亿元 同比增长95%

2023-02-08

今日最新!世体:巴萨想7月初为阿劳霍完成一线队注册,以符合财政公平要求

2023-02-08

正义词语的解析及近义词_天天快看

2023-02-08

当前热讯:无锡鼋头渚门票价格多少(附优惠、免票人群)

2023-02-08

当日快讯:四川资中18岁女生遗体在江中被发现,案件侦办工作仍在进行中 天天新视野

2023-02-08