Elasticsearch基础篇(八):常用查询以及使用Java Api Client进行检索

news2024/10/2 16:20:30

ES常用查询以及使用Java Api Client进行检索

1. 检索需求

参照豆瓣阅读的列表页面

需求:

  • 检索词需要在数据库中的题名、作者和摘要字段进行检索并进行高亮标红
  • 返回的检索结果需要根据综合、热度最高、最近更新、销量最高、好评最多进行排序
  • 分页数量为10,并且返回检索到的总数量

image-20231220150501858

2. 建立测试环境

2.1 根据需求建立es字段

mapping.json

 {
  "mappings": {
    "properties": {
      "title": {
        "analyzer": "standard",
        "type": "text"
      },
      "author": {
        "analyzer": "standard",
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      },
      "contentDesc": {
        "analyzer": "standard",
        "type": "text"
      },
      "wordCount": {
        "type": "double"
      },
      "price": {
        "type": "double"
      },
      "cover": {
        "type": "keyword"
      },
      "heatCount": {
        "type": "integer"
      },
      "updateTime": {
        "type": "date"
      }
    }
  }
}

映射字段说明:

  1. id(长整型): 表示唯一标识的字段,类型为long
  2. title(文本类型): 用于存储文档标题的字段,类型为text。指定默认的标准分析器(analyzer)为standard
  3. author(文本类型): 存储文档作者的字段,同样是text类型。除了使用标准分析器外,还定义额外的关键字(keyword)字段,该关键字字段通常用于==精确匹配和聚合==操作。
  4. contentDesc(文本类型): 存储文档内容描述的字段,同样是text类型,使用标准分析器。
  5. wordCount(双精度浮点型): 存储文档字数的字段,类型为double。通常用于存储浮点数值。
  6. price(双精度浮点型): 存储文档价格的字段,同样是double类型。用于存储浮点数值,例如书籍的价格。
  7. cover(关键字类型): 存储文档封面的字段,类型为keyword。关键字字段通常用于精确匹配。
  8. heatCount(整型): 存储热度计数的字段,类型为integer。通常用于热度排序
  9. updateTime(日期类型): 存储文档更新时间的字段,类型为date。用于最近更新排序

2.2 创建索引和映射

image-20231220154508492

2.3 增加测试数据

 POST /douban/_doc/1001
 {
    "title":"诗云",
    "author":"刘慈欣",
    "contentDesc":"伊依一行三人乘坐一艘游艇在南太平洋上做吟诗航行,平时难得一见的美洲大陆清晰地显示在天空中,在东半球构成的覆盖世界的巨大穹顶上,大陆好像是墙皮脱落的区域…",
    "wordCount":18707,
    "price":6.99,
    "cover":"https://pic.arkread.com/cover/ebook/f/19534800.1653698501.jpg!cover_default.jpg",
    "heatCount":201,
    "updateTime":"2023-12-20"
 }
 
  POST /douban/_doc/1002
 {
    "title":"三体2·黑暗森林",
    "author":"刘慈欣",
    "contentDesc":"征服世界的中国科幻神作!包揽九项世界顶级科幻大奖!《三体》获得第73届“雨果奖”最佳长篇奖!",
    "wordCount":318901,
    "price":32.00,
    "cover":"https://pic.arkread.com/cover/ebook/f/110344476.1653700299.jpg!cover_default.jpg",
    "heatCount":545,
    "updateTime":"2023-12-25"
 }
 
  POST /douban/_doc/1003
 {
    "title":"三体前传:球状闪电",
    "author":"刘慈欣",
    "contentDesc":"征服世界的中国科幻神作!包揽九项世界顶级科幻大奖!《三体》获得第73届“雨果奖”最佳长篇奖!",
    "wordCount":181119,
    "price":35.00,
    "cover":"https://pic.arkread.com/cover/ebook/f/116984494.1653699856.jpg!cover_default.jpg",
    "heatCount":765,
    "updateTime":"2022-11-12"
 }
 
  POST /douban/_doc/1004
 {
    "title":"全频带阻塞干扰",
    "author":"刘慈欣",
    "contentDesc":"这是一个场面浩大而惨烈的故事。21世纪的某年,以美国为首的北约发起了对俄罗斯的全面攻击。在残酷的保卫战中,俄国的电子战设备无力抵挡美国的进攻",
    "wordCount":28382,
    "price":6.99,
    "cover":"https://pic.arkread.com/cover/ebook/f/19532617.1653698557.jpg!cover_default.jpg",
    "heatCount":153,
    "updateTime":"2021-03-23"
 }

3. 执行查询

3.1 主键查询

# 此种方式已过时,不推荐
GET /douban/_doc/1001

# 推荐此种方式
POST /douban/_search
{
    "query": {
        "match": {
            "_id": 1001
        }
    }
}

3.2 全量查询

POST /douban/_search
{
    "query": {
        "match_all": { 
        }
    }
}

3.3 分页查询

POST /douban/_search
{
    "query": {
        "match_all": { 
        }
    },
    "from":1,
    "size":2
}

3.4 排序查询

POST /douban/_search
{
  "query": {
    "match_all": {
    }
  },
  "sort": [
    {
      "price": { 
        "order": "desc" 
      }
    }
  ]
}

3.5 全文检索

POST /douban/_search
{
  "query": {
    "match": {
      "title":"三体球闪"
  }
 }
}

检索结果:

image-20231220170628892

3.6 高亮检索

POST /douban/_search
{
    "query": {
        "match": {
            "title": "三体球闪"
        }
    },
    "highlight": {
        "fields": {
            "title": {
                "pre_tags": [
                    "<font style='red'>"
                ],
                "post_tags": [
                    "</font>"
                ]
            }
        }
    }
}

image-20231220172424036

3.7 bool查询

题名进行全文检索包含‘三体球闪’,并且价格为‘35’的数据

POST /douban/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "title": "三体球闪"
                    }
                },
                {
                    "term": {
                        "price": 35
                    }
                }
            ]
        }
    }
}

3.7 多字段全文检索

对题名、作者、摘要进行全文匹配,同时根据三个字段进行高亮标红

POST /douban/_search
{
    "query": {
        "multi_match": {
            "query": "三体球闪",
            "fields": [
                "title",
                "author",
                "contentDesc"
            ]
        }
    },
    "highlight": {
        "fields": {
            "title": {},
            "author": {},
            "contentDesc": {}
        }
    }
}

image-20231220173414933

3.8 综合检索

对题名、作者、摘要进行全文匹配,同时根据三个字段进行高亮标红

增加分页条件查询、增加更新日期降序排序、同时返回需要的必备字段

POST /douban/_search
{
    "query": {
        "multi_match": {
            "query": "三体球闪",
            "fields": [
                "title",
                "author",
                "contentDesc"
            ]
        }
    },
    "from": 0,
    "size": 2,
    "_source": [
        "title",
        "author",
        "price",
        "wordCount"
    ],
    "sort": [
        {
            "updateTime": {
                "order": "desc"
            }
        }
    ],
    "highlight": {
        "fields": {
            "title": {
            },
            "author": {
            },
            "contentDesc": {
            }
        }
    }
}

image-20231221092538555

4. Spring项目集成elasticsearch

参考文档:[Installation | Elasticsearch Java API Client 7.17] | Elastic

4.1 创建Spring项目并引入es依赖

image-20231222145917463 image-20231222150055190

如果希望使用java8,就打开pom.xml修改parent版本和java.version的值,然后点击刷新maven

image-20231222152132304

在Elasticsearch7.15版本之后,Elasticsearch官方将它的高级客户端RestHighLevelClient标记为弃用状态。同时推出了全新的Java API客户端Elasticsearch Java API Client,该客户端也将在Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。

Api名称介绍
TransportClient-废弃,8.x删除基于TCP方式访问,只支持JAVA,7.x开始弃用,8.x删除.
Rest Lower Level Rest Client低等级RestApi,最小依赖。
Rest High Level Rest Client废弃,未说明删除时间高等级的RestApi,基于低等级Api,7.15开始弃用,但没有说明会删除。用低等级Api替换。
RestClient基于Http的Api形式,跨语言,推荐使用,底层基于低等级Api,7.15才开始提供
<dependency>
	<groupId>co.elastic.clients</groupId>
	<artifactId>elasticsearch-java</artifactId>
	<version>7.17.11</version>
</dependency>

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.12.3</version>
</dependency>

<!-- 此依赖的作用是解决:lassNotFoundException: jakarta.json.spi.JsonProvider
     参考:https://github.com/elastic/elasticsearch-java/issues/311 -->
<dependency>
    <groupId>jakarta.json</groupId>
    <artifactId>jakarta.json-api</artifactId>
    <version>2.0.1</version>
</dependency>

完整依赖如下:注意 properties中一定要加 <elasticsearch.version>7.17.11</elasticsearch.version>,否则会导致无法覆盖父引用中依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.15</version>
        <relativePath/>
    </parent>
    <groupId>com.zhouquan</groupId>
    <artifactId>client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>client</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>8</java.version>
        <lombok.version>1.18.22</lombok.version>
        <elasticsearch.version>7.17.11</elasticsearch.version>
        <jakarta.version>2.0.1</jakarta.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>7.17.11</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>

        <!-- 此依赖的作用是解决:lassNotFoundException: jakarta.json.spi.JsonProvider
         参考:https://github.com/elastic/elasticsearch-java/issues/311 -->
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>jakarta.json</artifactId>
            <version>${jakarta.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <!-- Apache Commons IO -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4.2 增加es客户端配置类

交给spring进行管理,使用时通过@Resource private ElasticsearchClient client; 注入即可使用

@Configuration
@Slf4j
public class EsClient {

    @Resource
    private EsConfig esConfig;

    /**
     * Bean 定义,用于创建 ElasticsearchClient 实例。
     *
     * @return 配置有 RestClient 和传输设置的 ElasticsearchClient 实例。
     */
    @Bean
    public ElasticsearchClient elasticsearchClient() {
        // 使用 Elasticsearch 集群的主机和端口配置 RestClient
        List<String> clusterNodes = esConfig.getClusterNodes();
        HttpHost[] httpHosts = clusterNodes.stream().map(HttpHost::create).toArray(HttpHost[]::new);

        // Create the low-level client
        RestClient restClient = RestClient.builder(httpHosts).build();

        // JSON 序列化
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

        ElasticsearchClient client = new ElasticsearchClient(transport);

        // 打印连接信息
        log.info("Elasticsearch Client 连接节点信息:{}", Arrays.toString(httpHosts));

        return client;
    }

}

4.3 使用 Java API Client 创建索引

参考链接:Using the Java API Client

image-20240109152629604

/**
 * 创建索引
 */
@Test
void createIndex() throws IOException {
    ClassLoader classLoader = ResourceLoader.class.getClassLoader();
    InputStream input = classLoader.getResourceAsStream("mapping/douban.json");

    CreateIndexRequest req = CreateIndexRequest.of(b -> b
            .index("douban_v1")
            .withJson(input)
    );

    boolean created = client.indices().create(req).acknowledged();
    log.info("是否创建成功:" + created);
}

4.4 保存文档

实体类 DouBan.java

package com.zhouquan.client.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author ZhouQuan
 * @description todo
 * @date 2024-01-09 15:54
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DouBan {

    private String id;

    private String title;

    private String author;

    private String contentDesc;

    private Integer wordCount;

    private Double price;

    private String cover;

    private Integer heatCount;

    private Date updateTime;
}

4.4.1 索引单个文档

public String indexSingleDoc() {
        IndexResponse indexResponse;
        DouBan douBan = new DouBan("1211", "河边的错误", "余华", "内容简介", 50000, 52.5, "封面1", 74, new Date());
        try {
            // 使用流式dsl保存
            indexResponse = client.index(i -> i
                    .index(indexName)
                    .id(douBan.getId())
                    .document(douBan));

            // 使用 Java API Client的静态of()方法
            IndexRequest<DouBan> objectIndexRequest = IndexRequest.of(i -> i
                    .index(indexName)
                    .id(douBan.getId())
                    .document(douBan));
            IndexResponse ofIndexResponse = client.index(objectIndexRequest);

            // 使用经典版本
            IndexRequest.Builder<DouBan> objectBuilder = new IndexRequest.Builder<>();
            objectBuilder.index(indexName);
            objectBuilder.id(douBan.getId());
            objectBuilder.document(douBan);
            IndexResponse classicIndexResponse = client.index(objectBuilder.build());

            // 异步保存
            asyncClient.index(i -> i
                    .index("douban")
                    .id(douBan.getId())
                    .document(douBan)
            ).whenComplete((response, exception) -> {
                if (exception != null) {
                    log.error("Failed to index", exception);
                } else {
                    log.info("Indexed with version " + response.version());
                }
            });

            // 索引原始json数据
            IndexResponse response = null;
            try {
                String jsonData = " {\"id\":\"1741\",\"title\":\"三体\",\"author\":\"刘慈欣\",\"contentDesc\":\"内容简介\",\"wordCount\":50000,\"price\":52.5}";
                Reader input = new StringReader(jsonData);
                IndexRequest<JsonData> request = IndexRequest.of(i -> i
                        .index("douban_v1")
                        .withJson(input)
                );

                response = client.index(request);
                log.info("Indexed with version " + response.version());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return Result.Created.equals(indexResponse.result()) + "";
    }

4.4.2 批量索引文档

/**
 * 批量保存
 *
 * @throws IOException
 */
@Test
void bulkSave() throws IOException {

    DouBan douBan1 = new DouBan("1002", "题名1", "余华", "内容简介", 50000, 52.5, "封面1", 74, new Date());
    DouBan douBan2 = new DouBan("1003", "题名2", "余华", "内容简介", 50000, 52.5, "封面1", 74, new Date());
    DouBan douBan3 = new DouBan("1004", "题名3", "余华", "内容简介", 50000, 52.5, "封面1", 74, new Date());
    List<DouBan> douBanList = new ArrayList<>();
    douBanList.add(douBan1);
    douBanList.add(douBan2);
    douBanList.add(douBan3);

    BulkRequest.Builder br = new BulkRequest.Builder();
    for (DouBan douBan : douBanList) {
        br.operations(op -> op
                .index(idx -> idx
                        .index("products")
                        .id(douBan.getId())
                        .document(douBan)
                )
        );
    }

    BulkResponse result = client.bulk(br.build());
    if (result.errors()) {
        log.error("Bulk had errors");
        for (BulkResponseItem item : result.items()) {
            if (item.error() != null) {
                log.error(item.error().reason());
            }
        }
    }
}

4.4.3 原始数据批量索引文档

/**
 * 原始json数据批量保存
 *
 * @throws IOException
 */
@Test
void rawDataBulkSave() throws IOException {

    File logDir = new File("D:\\IdeaProjects\\client\\src\\main\\resources\\data");

    File[] logFiles = logDir.listFiles(
            file -> file.getName().matches("bulk*.*\\.json")
    );

    BulkRequest.Builder br = new BulkRequest.Builder();

    for (File file : logFiles) {
        FileInputStream input = new FileInputStream(file);
        BinaryData data = BinaryData.of(IOUtils.toByteArray(input), ContentType.APPLICATION_JSON);

        br.operations(op -> op
                .index(idx -> idx
                        .index("douban_v1")
                        .document(data)
                )
        );
    }

    BulkResponse result = client.bulk(br.build());
    if (result.errors()) {
        List<BulkResponseItem> items = result.items();
        items.forEach(x -> System.out.println(x.error()));
    }
    log.info("是否成功批量保存:" + !result.errors());
}

4.5 获取单个文档

// 根据id获取数据并装载为java对象
GetRequest getRequest = GetRequest.of(x -> x.index("douban_v1").id("1002"));
GetResponse<DouBan> douBanGetResponse = client.get(getRequest, DouBan.class);
DouBan source = douBanGetResponse.source();

GetResponse<DouBan> response = client.get(g -> g
                .index(indexName)
                .id(id),
        DouBan.class
);

if (!response.found()) {
    throw new BusinessException("未获取到指定id的数据");
}

DouBan douBan = response.source();
log.info("资料title: " + douBan.getTitle());
return douBan;
// 根据id获取原始JSON数据
GetResponse<ObjectNode> response1 = client.get(g -> g
                .index(indexName)
                .id(id),
        ObjectNode.class
);

if (response1.found()) {
    ObjectNode json = response1.source();
    String name = json.get("title").asText();
    log.info(" title " + name);
} else {
    log.info("data not found");
}
return null;

4.6 文档检索

4.6.1 普通的搜索查询

public List<DouBan> search(String searchText) {

    SearchResponse<DouBan> response = null;
    try {
        response = client.search(s -> s
                        .index(indexName)
                        .query(q -> q
                                .match(t -> t
                                        .field("title")
                                        .query(searchText)
                                )
                        ),
                DouBan.class
        );
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    TotalHits total = response.hits().total();
    boolean isExactResult = total.relation() == TotalHitsRelation.Eq;

    if (isExactResult) {
        log.info("There are " + total.value() + " results");
    } else {
        log.info("There are more than " + total.value() + " results");
    }

    List<Hit<DouBan>> hits = response.hits().hits();
    List<DouBan> list = new ArrayList<>();
    for (Hit<DouBan> hit : hits) {
        DouBan DouBan = hit.source();
        list.add(DouBan);
        log.info("Found DouBan " + DouBan.getTitle() + ", score " + hit.score());
    }
    return list;
}

4.6.2 嵌套搜索查询

public List<DouBan> search2(String searchText, Double price) {

    Query titleQuery = MatchQuery.of(m -> m
            .field("title")
            .query(searchText)
    )._toQuery();

    Query rangeQuery = RangeQuery.of(r -> r
            .field("price")
            .gte(JsonData.of(price))
    )._toQuery();

    try {
        SearchResponse<DouBan> search = client.search(s -> s
                        .index(indexName)
                        .query(q -> q
                                .bool(b -> b
                                        .must(titleQuery)
                                        .must(rangeQuery)
                                )
                        )
                ,
                DouBan.class
        );

        // 解析检索结果
        List<DouBan> douBanList = new ArrayList<>();
        List<Hit<DouBan>> hits = search.hits().hits();
        for (Hit<DouBan> hit : hits) {
            DouBan douBan = hit.source();
            douBanList.add(douBan);
        }
        return douBanList;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

4.6.3 模板搜索

// 创建模板,返回搜索请求正文的存储脚本
client.putScript(r -> r
        .id("query-script")
        .script(s -> s
                .lang("mustache")
                .source("{\"query\":{\"match\":{\"{{field}}\":\"{{value}}\"}}}")
        ));

// 执行请求
SearchTemplateResponse<DouBan> response = client.searchTemplate(r -> r
                .index("douban_v1")
                .id("query-script")
                .params("field", JsonData.of("title"))
                .params("value", JsonData.of("题名")),
        DouBan.class
);

// 结果解析
List<Hit<DouBan>> hits = response.hits().hits();
for (Hit<DouBan> hit: hits) {
    DouBan DouBan = hit.source();
    log.info("Found DouBan " + DouBan.getTitle() + ", score " + hit.score());
}

4.7 文档聚合

Query query = MatchQuery.of(t -> t
        .field("title")
        .query(searchText))._toQuery();

Aggregation authorAgg = AggregationBuilders.terms().field("author").build()._toAggregation();

SearchResponse<DouBan> response = null;

response = client.search(s -> s
                .index(indexName)
                .query(query)
                .aggregations("author", authorAgg),
        DouBan.class
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1412843.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode 代码格式化很短就换行,以及缩放设置

安装vetur 打开vscode设置settings.json { "editor.tabSize": 2,//缩进单位"vetur.format.defaultFormatter.html": "js-beautify-html","vetur.format.defaultFormatterOptions": {"js-beautify-html": {"wrap_line…

项目测试 手机系统 改串号 写IMEI 改MEID 改手机型号 等信息配置信息 演示视频 和一键新机

项目测试 手机系统 改串号 写IMEI 改MEID 改手机型号 等信息配置信息 演示视频 和配置说明 项目-手机系统支持直接改串号 IMEI MEID 手机型号 等信息配置信息 演示视频 支持 条形码 SN IMEI 1 IMEI 2 MEID 唯一SN 蓝牙地址 wifi地址 mac "一键新机"这个术语通常出现…

视频有点大能做二维码吗?视频转成二维码图片的方法

怎么把一个比较大的视频转二维码图片呢&#xff1f;现在很多人会以二维码为载体来存储视频文件&#xff0c;其他人只需要扫码生成二维码就可以观看视频。有的视频因为时间比较长&#xff0c;尺寸比较大&#xff0c;文件会比较大&#xff0c;那么几十几百m大小的视频如何快速制作…

不学前沿技术与朽木浮草何异 Java 10新特性

不学前沿技术与朽木浮草何异? Java 10新特性 ​ 发布于 2018 年 3 月 20 日&#xff0c;最知名的特性应该是 var 关键字&#xff08;局部变量类型推断&#xff09;的引入了&#xff0c;其他还有垃圾收集器改善、GC 改进、性能提升、线程管控等一批新特性。 概览&#xff08;…

Shell脚本------函数与数组

目录 一、函数 1、函数是什么&#xff1f; 2、函数的格式 3、函数的调用方法 ①脚本&#xff1a;查看当前操作系统 ②脚本二&#xff1a;函数备份yum线上源&#xff0c;创建yum本地源和清理缓存安装httpd 4、函数的返回值 5、函数传参 6、函数变量的作用范围 1、实例…

2024年【安全员-B证】考试技巧及安全员-B证操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-B证考试技巧参考答案及安全员-B证考试试题解析是安全生产模拟考试一点通题库老师及安全员-B证操作证已考过的学员汇总&#xff0c;相对有效帮助安全员-B证操作证考试学员顺利通过考试。 1、【多选题】《建筑施…

Rocky8 顺利安装 Airflow 并解决数据库报错问题

rocky是替代centos的服务器系统&#xff0c;稳定可靠。rocky8会比centos7新&#xff0c;可以支持更多服务软件的安装&#xff0c;免去升级各种库的麻烦&#xff0c;本文运行airflow服务就用rocky8系统。airflow是一个定时任务管理系统&#xff0c;功能强大&#xff0c;目前是ap…

机器学习算法(二)

一、朴素贝叶斯 朴素贝叶斯&#xff08;Naive Bayes&#xff09;是基于贝叶斯定理。它测量每个类的概率&#xff0c;每个类的条件概率给出 x 的值。这个算法用于分类问题&#xff0c;得到一个二进制“是 / 非”的结果。看看下面的方程式。 先验概率&#xff1a;即基于统计的概…

python基础学习-03 安装

python3 可应用于多平台包括 Windows、Linux 和 Mac OS X。 Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, 等等。)Win 9x/NT/2000Macintosh (Intel, PPC, 68K)OS/2DOS (多个DOS版本)PalmOSNokia 移动手机Windows CEAcorn/RISC OSBeOSAmigaVMS/OpenVMSQNXVxWorksP…

万物简单AIoT 端云一体实战案例学习 之 空气质量检测系统

学物联网,来万物简单IoT物联网!! 下图是本案的3步导学,每个步骤中实现的功能请参考图中的说明。 1、简介 环境污染、空气污染是人类一直所关心并且讨论的永恒话题,人们对优质的环境和健康的身体非常向往。因此,如果有一种可以检测周围环境的空气质量的设备并且环境数据…

各个阶段直播流程和运营重点

塑型期直播流程与运营重点 成长期直播流程与运营重点 成熟期直播流程与运营重点 小结

每个开发人员都应该知道的6个Nodejs库

Node.js被视为许多Web开发人员的理想运行时环境。它是世界上最流行的编程语言之一&#xff0c;Node.js提供了通过JavaScript库重用代码的能力&#xff0c;但是在项目中选择合适的库可能很困难。 有用的库可以缩短开发时间&#xff0c;并为您的Web应用程序提供几个优点&#xf…

Unity学习之坦克游戏制作(2)游戏场景的制作

文章目录 1. 基础场景的搭建2. 游戏主面板2.1 拼出面板2.2 创建新面板2.3 设置面板复用2.4 退出界面 3. 坦克基类3.1 创建基类脚本3.1.1 基类基本属性3.1.2 抽象开火函数3.1.3 受伤虚函数3.1.4 死亡虚函数 4 玩家——基础移动旋转摄像机跟随4.1 玩家对象脚本4.2 控制坦克移动4.…

22.Lambda 表达式

Lambda 表达式 1. 概况2. 函数式接口3. 格式3.1 完整格式3.2 省略格式 4. 代码示例5. 输出结果6. 注意事项 学习Lambda表达式之前最好先学会 匿名内部类 1. 概况 Lambda 表达式是一种在编程中用来表示匿名函数的简洁语法。它是基于函数式编程风格的一种特性&#xff0c;最初在…

2024.1.26每日一题

LeetCode 边权重均等查询 2846. 边权重均等查询 - 力扣&#xff08;LeetCode&#xff09; 题目描述 现有一棵由 n 个节点组成的无向树&#xff0c;节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges &#xff0c;其中 edges[i] [ui, vi,…

微信小程序(十六)slot插槽

注释很详细&#xff0c;直接上代码 上一篇 温馨提醒&#xff1a;此篇需要自定义组件的基础&#xff0c;如果不清楚请先看上一篇 新增内容&#xff1a; 1.单个插槽 2.多个插槽 单个插糟 源码&#xff1a; myNav.wxml <view class"navigationBar custom-class">…

【C++】C++入门基础讲解(一)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 导读 经过一段时间的C语言学习&#xff0c;我们以及基本掌握了C语言的知识&#xff0c;今天&#xff0c;我们就开始学习C&#xff0c;…

网络安全相关知识点总结

网络安全背景 网络空间安全 --- Cyberspace 2003年美国提出网络空间的概念 --- 一个由信息基础设施组成的互相依赖的网络。 我国官方文件定义&#xff1a;网络空间为继海&#xff0c;陆&#xff0c;空&#xff0c;天以外的第五大人类活动领域 阶段的变化&#xff1a; 通信保密阶…

七通道NPN 达林顿管GC2003,应用于计算机,工业和消费类产品中

GC2003 内部集成了 7 个 NPN 达林顿晶体管&#xff0c;连接的阵列&#xff0c;非常适合逻辑接口电平数字电路&#xff08;例 如 TTL&#xff0c;CMOS 或PMOS 上/NMOS&#xff09;和较高的电流/电压&#xff0c;如电灯电磁阀&#xff0c;继电器&#xff0c;打印机或其他类似的负…

Android App开发基础(1)—— App的开发特点

本文介绍基于Android系统的App开发常识&#xff0c;包括以下几个方面&#xff1a;App开发与其他软件开发有什么不一样&#xff0c;App工程是怎样的组织结构又是怎样配置的&#xff0c;App开发的前后端分离设计是如何运作实现的&#xff0c;App的活动页面是如何创建又是如何跳转…