分布式搜索 (二)

news2024/11/15 16:20:16

一、DSL 查询文档

1. DSL Query 的分类

Elasticsearch 提供了基于 JSON 的

DSL (Domain Specific  Language)

来定义查询

常见的查询类型包括:

查询所有:查询出所有数据,一般测

    试用

    例如:match_all

全文检索 (full text) 查询:利用分词器

   对用户输入内容分词,然后去倒排索引

   库中匹配。

   例如:match_query

              multi_match_query

精确查询:根据精确词条值查找数据,

   一般是查找 keyword、数值、日期、

   boolean 等类型字段。

   例如:ids、range 、term

地理 (geo) 查询:根据经纬度查询。

    例如:geo_distance

              geo_bounding_box

复合 (compound) 查询:复合查询可以

    将上述各种查询条件组合起来,合并查

    询条件

    例如:bool function_score   

查询 DSL 的基本语法:

GET /索引库名/_search

{

        "query":{

                "查询类型":{

                        "FIELD":"TEXT"

                }

        }

2. 全文检索查询

对用户输入内容分词,常用于搜索框搜索:

match 查询:全文检索查询的一种,会

    对用户输入内容分词,然后去倒排索引

    库检索,语法:

multi_match:与 match 查询类似,只

    不过允许同时查询多个字段,语法: 

 

 

3. 精准查询

精确查询一般是查找 keyword、数值、

日期、boolean 等类型字段,所以不会

对搜索条件分词

常见的有:

term:根据词条精确值查询

 

range:根据值的范围查询

 

 

4. 地理坐标查询

geo_bounding_box:查询 geo_point

    值落在某个矩形范围的所有文档

 

geo_distance:查询到指定中心点小

    于某个距离值的所有文档

 

5. 复合查询

fuction score:算分函数查询,可以控制

             文档相关性算分,控制文档排名

(1) 相关性算分

利用 match 查询时,文档结果会根据与搜

索词条的关联度打分 (_score),返回结果

时按照分值降序排列

TF-IDF:在 elasticsearch5.0 之前,

              会随着词频增加而越来越大

BM25:在 elasticsearch5.0 之后,会

            随着词频增加而增大,但增

            曲线会趋于水平

(2) Function Score Query

使用 function score query,可以修改文档

的相关性算分 (query score),根据新得到

的算分排序

function score query 定义的三要素:

过滤条件:哪些文档要加分

算分函数:如何计算 function score

加权方式:function score 与 query

                      score 如何运算 

(3) Boolean Query

布尔查询是一个或多个查询子句的组合

子查询的组合方式有:

must:必须匹配每个子查询,类似 “

should:选择性匹配子查询,类似 “

must_not:必须不匹配,不参与算分,

                  类似 “

filter:必须匹配,不参与算分 

 

二、搜索结果处理

1. 排序

es 支持对搜索结果排序,默认是根据

相关度算分 (_score) 来排序,可以排

序字段类型有:keyword 类型、数值

类型、地理坐标类型、日期类型等

 

 

2. 分页

es 默认情况下只返回 top10 的数据,

而如果要查询更多数据就需要修改分

页参数了,通过修改 from、size

数来控制要返回的分页结果

 (2) 深度分页问题

ES 是分布式的,所以会面临深度分页问题

例如:按 price 排序后,获取 from = 990,

          size =10 的数据:

① 在每个数据分片上都排序并查询前

    1000条文档

② 将所有节点的结果聚合,在内存中

    重新排序选出前1000条文档

③ 从这1000条中,选取从990开始的

    10条文档

  

如果搜索页数过深,或者结果集 (from

+ size) 越大,对内存和 CPU 的消耗也

越高,因此 ES 设定结果集查询的上限

是10000

深度分页解决方案:

search after:分页时需要排序,原

    理是从上一次的排序值开始,查询

    下一页数据 (推荐)

scroll:原理将排序数据形成快照

    保存在内存 (不推荐使用)

总结:

from + size

优点:支持随机翻页

缺点:深度分页问题,默认查询上限

          (from + size) 是10000

场景:百度、京东、谷歌、淘宝这样

          的随机翻页搜索

after search

优点:没有查询上限 (单次查询的 size

          不超过10000)

缺点:只能向后逐页查询,不支持随机

          翻页

场景:没有随机翻页需求的搜索,例如

          手机向下滚动翻页

scroll

优点:没有查询上限 (单次查询的 size

          不超过10000)

缺点:会有额外内存消耗,并且搜索

          果是非实时的

场景:海量数据的获取和迁移,从 ES

          7.1 开始不推荐

3. 高亮

在搜索结果中把搜索关键字突出显示

原理:

将搜索结果中的关键字用标签标记

来,在页面中给标签添加 css 样式

 搜索结果处理整体语法:

 

三、RestClient 查询文档

1. 快速入门

(1) 发起查询请求

request.source() 包含了查询、排序、

分页、高亮等所有功能

QueryBuilders 包含 match、term、

function_score、bool 等各种查询

(2) 解析响应 

 

es 返回的结果是一个 JSON 字符串,

结构包含:

hits:命中的结果
        total:总条数,其中的 value 是具

                 体的总条数值
        max_score:所有结果中得分最高

                             的文档的相关性算分
        hits:搜索结果的文档数组,其中

                的每个文档都是一个json对象
                _source:文档中的原始数据

                                也是json对象

所以解析响应结果,就是逐层解析 JSON 字

符串

@Test
void testMatchAll() throws IOException {
    // 1.准备Request
    SearchRequest request = new SearchRequest("hotel");
    // 2.准备DSL
    request.source()
        .query(QueryBuilders.matchAllQuery());
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    // 4.解析响应
    handleResponse(response);
}

private void handleResponse(SearchResponse response) {
    // 4.解析响应
    SearchHits searchHits = response.getHits();
    // 4.1.获取总条数
    long total = searchHits.getTotalHits().value;
    System.out.println("共搜索到" + total + "条数据");
    // 4.2.文档数组
    SearchHit[] hits = searchHits.getHits();
    // 4.3.遍历
    for (SearchHit hit : hits) {
        // 获取文档source
        String json = hit.getSourceAsString();
        // 反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println("hotelDoc = " + hotelDoc);
    }
}

2. match 查询

与 match_all 差别是查询条件,也就是

query 的部分

Java 代码上的差异主要是 request.source().

query() 中的参数

 

@Test
void testMatch() throws IOException {
    // 1.准备Request
    SearchRequest request = new SearchRequest("hotel");
    // 2.准备DSL
    request.source()
        .query(QueryBuilders.matchQuery("all", "如家"));
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    handleResponse(response);

}

3. 精确查询

与之前的查询相比,差异同样在查询条件

 

 

4. 复合查询--Boolean Query

 

@Test
void testBool() throws IOException {
    // 1.准备Request
    SearchRequest request = new SearchRequest("hotel");
    // 2.准备DSL
    // 2.1.准备BooleanQuery
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    // 2.2.添加term
    boolQuery.must(QueryBuilders.termQuery("city", "杭州"));
    // 2.3.添加range
    boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));

    request.source().query(boolQuery);
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    handleResponse(response);

}

5. 排序、分页

搜索结果的排序和分页是与 query

的参数,因此同样是使用 request.

source() 来设置

 

@Test
void testPageAndSort() throws IOException {
    // 页码,每页大小
    int page = 1, size = 5;

    // 1.准备Request
    SearchRequest request = new SearchRequest("hotel");
    // 2.准备DSL
    // 2.1.query
    request.source().query(QueryBuilders.matchAllQuery());
    // 2.2.排序 sort
    request.source().sort("price", SortOrder.ASC);
    // 2.3.分页 from、size
    request.source().from((page - 1) * size).size(5);
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    handleResponse(response);

}

6. 高亮

与之前代码差异较大:

① 查询的DSL:其中除了查询条件,

    需要添加高亮条件,同样是与 query

    同级

② 结果解析:结果除了要解析 _source

    文档数据,还要解析高亮结果

(1) 请求的 DSL 构建 

 

@Test
void testHighlight() throws IOException {
    // 1.准备Request
    SearchRequest request = new SearchRequest("hotel");
    // 2.准备DSL
    // 2.1.query
    request.source().query(QueryBuilders.matchQuery("all","如家"));
    // 2.2.高亮
    request.source().highlighter(new HighlightBuilder().
                                    field("name").requireFieldMatch(false));
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    handleResponse(response);

}

 (2) 结果解析

 

private void handleResponse(SearchResponse response) {
    // 4.解析响应
    SearchHits searchHits = response.getHits();
    // 4.1.获取总条数
    long total = searchHits.getTotalHits().value;
    System.out.println("共搜索到" + total + "条数据");
    // 4.2.文档数组
    SearchHit[] hits = searchHits.getHits();
    // 4.3.遍历
    for (SearchHit hit : hits) {
        // 获取文档source
        String json = hit.getSourceAsString();
        // 反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        // 获取高亮结果
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if (!CollectionUtils.isEmpty(highlightFields)) {
            // 根据字段名获取高亮结果
            HighlightField highlightField = highlightFields.get("name");
            if (highlightField != null) {
                // 获取高亮值
                String name = highlightField.getFragments()[0].string();
                // 覆盖非高亮结果
                hotelDoc.setName(name);
            }
        }
        System.out.println("hotelDoc = " + hotelDoc);
    }
}

四、数据聚合

1. 聚合的种类

聚合 (aggregations) 可以实现对文档

数据的统计、分析、运算,参与聚合

的字段类型必须是:keyword、数值、

日期、布尔

聚合常见的有三类:

聚合 (Bucket):用来对文档做分组

     TermAggregation:按照文档字段值

                                   分组

     Date Histogram:按照日期阶梯分组,

         例如一周为一组,或者一月为一组

度量聚合 (Metric):用以计算一些值,

     Avg:求平均值         

     Max:求最大值

     Min:求最小值

     Stats:同时求 max、min、avg、sum 等

管道聚合 (pipeline):其它聚合的结果

                                      为基础做聚合

2. DSL 实现聚合

(1) DSL 实现 Bucket 聚合

聚合必须的三要素:

① 聚合名称

② 聚合类型

③ 聚合字段

  2) 聚合结果排序

默认情况下,Bucket 聚合会统计 Bucket

内的文档数量,记为 _count,并且按照

_count 降序排序

可以修改结果排序方式:

 

   3) 限定聚合范围

默认情况下,Bucket 聚合是对索引库

所有文档做聚合,我们可以限定

聚合的文档范围,只要添加 query 条

件即可

 (2) DSL 实现 Metrics 聚合

 

3. RestAPI 实现聚合

  2) 聚合结果解析 

@Test 
Void testAggregation() throws IOException {
    // 1. 准备 Request
    SearchRequest request = new SearchRequest("hotel");
    // 2. 准备 DSL
    // 2.1 设置 size
    request.source().size(0);
    // 2.2 聚合
    request.source().aggregation(AggregationBuilders
            .terms("brandAgg")
            .field("brand")
            .size(10)
    );
    // 3. 发出请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4. 解析结果
    Aggregations aggregations = response.getAggregations();
    // 4.1 根据聚合名称获取聚合结果
    Terms brandTerms = aggregations.get("brandAgg");
    // 4.2 获取 buckets
    List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
    // 4.3 遍历
    for (Terms.Bucket bucket : buckets) {
        //4.4 获取 key
        String key = bucket.getKeyAsString();
        System.out.println(key);
    }
}

 

五、自动补全

1. 拼音分词器

要实现根据字母做补全,就必须对文档

按照拼音分词,需要安装拼音分词插件

GitHub - medcl/elasticsearch-analysis-pinyin: This Pinyin Analysis plugin is used to do conversion between Chinese characters and Pinyin.

2. 自定义分词器

es 中分词器 (analyzer) 的组成包含三部分:

character filters:在 tokenizer 之前

   对文本进行处理,例如删除字符、替

   换字符

tokenizer:将文本按照一定的规则切

   割成词条 (term),例如 keyword,就

   是不分词;还有ik_smart

tokenizer filter:将 tokenizer 输出的

   词条做进一步处理,例如大小写转换、

   同义词处理、拼音处理等

在创建索引库时,通过 settings 来配置自定

义的 analyzer(分词器):

 

 

// 自定义拼音分词器
PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": { 
        "my_analyzer": { 
          "tokenizer": "ik_max_word",
          "filter": "py"
        }
      },
      "filter": {
        "py": { 
          "type": "pinyin",
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  }
}

① 拼音分词器适合在创建倒排索引

的时候使用,但不能在搜索的时候

使用

② 因此字段在创建倒排索引时应该

用 my_analyzer 分词器,字段在搜

索时应该使用 ik_smart 分词器

 

3. 自动补全查询

es 中使用 completion suggester 查询

来实现自动补全功能,匹配以用户输

入内容开头的词条并返回

为了提高补全查询的效率,对于文档中字

段的类型有一些约束:

① 参与的字段必须是 completion 类型

② 字段的内容一般是用来补全的多个

    词条形成的数组

// 自动补全查询
POST /test/_search
{
  "suggest": {
    "title_suggest": {
      "text": "s", // 关键字
      "completion": {
        "field": "title", // 补全字段
        "skip_duplicates": true, // 跳过重复的
        "size": 10 // 获取前10条结果
      }
    }
  }
}

4. RestAPI 实现自动补全

@Test 
void testSuggest() throws IOEvxception {
    // 1. 准备 Request
    SearchRequest request = new SearchRequest("hotel");
    // 2. 准备 DSL
    request.source().suggest(new SuggestBuilder().addSuggestion(
                "suggestions"
            SuggestBuilders.completionSuggestion("suggestion")
                    .prefix("h")
                    .skipDuplicates(true)
                    .size(10)
    ));
    // 3. 发出请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4. 处理结果
    Suggest suggest = response.getSuggest();
    // 4.1 根据名称获取补全结果
    CompletionSuggestion suggestion = suggest.getSuggestion("hotelSuggestion");
    // 4.2 获取 options 并遍历
    for (CompletionSuggestion.Entry.Option option : suggestion.getOptions()) {
        //4.3 获取一个 option 中的 text,也就是补全的词条
        String text = option.getText().string();
        System.out.println(text);
    }
}

六、数据同步

数据同步:es 中的数据来自于 mysql

                  数据库,因此 mysql 数据

                  发生改变时,es 也必须跟

                  着改变

跨微服务的数据同步问题解决方案

同步调用

    优点:实现简单,粗暴

    缺点:业务耦合度高

异步通知

    优点:低耦合,实现难度一般

    缺点:依赖 mq 的可靠性

监听 binlog

    优点:完全解除服务间耦合

    缺点:开启 binlog 增加数据库负担、

              实现复杂度高

七、集群

单机的 es 做数据存储,必然面临两个问

题,海量数据存储问题和单点故障问题

解决方案:

海量数据存储问题:将索引库从逻辑上

    拆分为N个分片(shard),存储到多个节

    点

单点故障问题:将分片数据在不同节点

    备份(replica)

1. 搭建 ES 集群

  (1) 创建 es 集群

   1) 编写一个 docker-compose 文件,内容如下:

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic

volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

  2) es 运行需要修改一些 linux 系统权限,

      修改 /etc/sysctl.conf 文件

① 添加 vm.max_map_count=262144

② 执行命令 sysctl -p

  3) 通过 docker-compose 文件启动集群

docker-compose up -d

(2) 集群状态监控

使用 cerebro 来监控 es 集群状态

GitHub - lmenezes/cerebro

(3) 创建索引库

方法一:利用 kibana 的 DevTools 创建索引库

PUT /itcast
{
  "settings": {
    "number_of_shards": 3, // 分片数量
    "number_of_replicas": 1 // 副本数量
  },
  "mappings": {
    "properties": {
      // mapping映射定义 ...
    }
  }
}

方法二:利用 cerebro 创建索引库

 

4) 查看分片效果

回到首页,即可查看索引库分片效果:

  

2. 集群脑裂问题

(1) ES 集群的节点角色

(2) ES 集群的分布式查询

es 中的每个节点角色都有自己不同

的职责,因此建议集群部署时,每

个节点都有独立的角色 

各节点的作用: 

aster eligible:参与集群选主;主节点可

    以管理集群状态、管理分片信息、处理创

    建和删除索引库的请求

data:数据的 CRUD

coordinator:路由请求到其它节点;合并

                         查询到的结果,返回给用户 

 (3) ES 集群的脑裂

默认情况下,每个节点都是 master eligible

节点,因此一旦 master 节点宕机,其它候

选节点会选举一个成为主节点,当主节点

与其他节点网络故障时,可能发生脑裂问题

为了避免脑裂,需要要求选票超过 (eligible

节点数量 + 1) / 2 才能当选为主,因此

eligible 节点数量最好是奇数,对应配置项

discovery.zen.minimum_master_nodes

在 es7.0 以后,已经成为默认配置,因此一

般不会发生脑裂问题

3. 集群分布式存储

新增文档时,应该保存到不同分片,保证

数据均衡

coordinating node 通过 hash 算法计算文档应该

存储到哪个分片:

shard = hash(_routing) % number_of_shards

① _routing 默认是文档的 id

② 算法与分片数量有关,因此索引库一旦

    创建,分片数量不能修改

 

4. 集群分布式查询

es 查询分成两个阶段:

scatter phase分散阶段,coordinating

    node 会把请求分发到每一个分片

gather phase聚集阶段,coordinating

    node 汇总 data node 的搜索结果,并处

    理为最终结果集返回给用户

5. 集群故障转移

集群的 master 节点会监控集群中的节点状

态,如果发现有节点宕机,会立即将宕机节

点的分片数据迁移到其它节点,确保数据安

全,这个叫做故障转移

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

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

相关文章

C++数据结构笔记(8)循环链表实现

1.循环链表与单链表的区别在于尾部结点存在指向头结点的指针 2.无论尾部结点指向第一个结点&#xff08;头结点&#xff09;还是第二个结点&#xff08;第一个有效结点&#xff09;&#xff0c;都可以被称为循环链表 3.判断循环结束的两种方式&#xff1a;遍历次数等于size;或…

《深度探索c++对象模型》笔记

非原创&#xff0c;在学习 1 关于对象&#xff08;Object Lessons&#xff09; 这里最开始从C语言的结构体引出C中的”抽象数据类型&#xff08;ADT&#xff09;“。 而加上封装之后&#xff0c;布局成本没有增加&#xff0c;三个data member直接内含在每一个class object之中…

深入选择屏幕

2.3.4.4 屏幕输入报表筛选条件等 &--------------------------------------------------------------------- *& selection-screen /option/parameter:屏幕输入报表赛选条件 *& TABLES . *selection-screen begin of block test select-options: selection-screen…

PHY芯片快速深度理解

摘要&#xff1a; 什么是phy 为什么要熟悉RJ45网口 网络七层协议 两个模块进行通信 什么是MDIO协议 MDIO的作用 MDIO没那么重要 MDIO读写时序 为什么说读取的phy最多32个 什么是phy 物理层芯片称为PHY、数据链路层芯片称为MAC。 可以看到PHY的数据是RJ45网络接口&am…

linux常见指令下

接下来我们就聊聊linux的后面十条指令。 一:echo 作用是往显示器输出内容&#xff0c;和printf类型&#xff0c;但是该指令最核心的是与之相关的一些概念 概念1.输出重定向&#xff1a; echo不仅可以向显示打印内容&#xff0c;还可以向文件输出内容&#xff0c;本应该输出到…

在服务器上启动springboot项目

环境搭建&#xff1a;要在服务器上运行SpringBoot Web项目&#xff0c;需要先在服务器上安装JDK&#xff08;CentOS系统安装JDK参考&#xff1a;http://t.csdn.cn/0zYml&#xff09; 第一步&#xff1a;创建项目 创建一个简单的springboot项目&#xff0c;并通过测试&#xf…

Java Web Servlet (2)23.7.8

1.7 urlPattern配置 Servlet类编写好后&#xff0c;要想被访问到&#xff0c;就需要配置其访问路径&#xff08;urlPattern&#xff09; 一个Servlet,可以配置多个urlPattern package com.itheima.web;import javax.servlet.ServletRequest; import javax.servlet.ServletRes…

嵌入式基础知识-流水线

提到流水线&#xff0c;最先想到的可能是流水线车间中的产品制造过程。 工业上的流水线&#xff0c;又称装配线&#xff0c;指每一个生产单位只专注处理某一个片段的工作&#xff0c;以提高工作效率及产量。 在计算机领域中&#xff0c;也有流水线的概念&#xff0c;其核心原理…

互联网医院系统定制|互联网医院在线诊疗平台

互联网医院系统对医院有以下几个方面的帮助&#xff1a;   提升医疗服务效率&#xff1a;互联网医院系统可以为医院提供在线挂号、在线问诊、远程会诊等功能&#xff0c;减少患者排队等待时间&#xff0c;提高医疗服务效率。   扩大服务范围&#xff1a;互联网医院系统可以…

【数据结构二叉树OJ系列】6、平衡二叉树

目录 题述&#xff1a; 思路&#xff1a; 正确代码如下&#xff1a; 时间复杂度分析&#xff1a; 现让你把代码优化时间复杂度为O&#xff08;N&#xff09; 思路&#xff1a; 题述&#xff1a; 给定一个二叉树&#xff0c;判断他是否是高度平衡的二叉树。 本题中&#xf…

HttpRunner自动化之接口关联和常用断言

接口关联 第一个test接口获取token,并提取出存储到变量中&#xff0c;在第二个test接口中直接调用该变量&#xff0c;如下图 # 接口关联 - config:name: 微信接口base_url: https://api.weixin.qq.com - test:name: 获取tokenrequest:url: /cgi-bin/tokenmethod: GETparams:g…

在vue3项目中加载Cesium立体地形信息并调整初始化角度

在vue3项目中加载Cesium立体地形信息并调整初始化角度 使用vite创建vue3项目 npm create vitelatestcd到创建的项目文件夹中 npm install安装Cesium npm i cesium vite-plugin-cesium vite -D配置 &#xff08;1&#xff09;在项目的vite.config.js文件中添加&#xff1a; impo…

Java模拟cookie登陆操作

Java模拟cookie登陆操作 在使用java访问URL时&#xff0c;如果该URL需要身份验证&#xff0c;那么就不能够直接访问&#xff0c;因为没有登陆。那么&#xff0c;如何解决这个问题呢&#xff1f; 方法是使用java模拟登陆&#xff0c;登陆后记录下cookie信息&#xff0c;在下次发…

【算法集训之线性表篇】Day 07

文章目录 题目基本设计思想代码实现效果 题目 一个长度为L(L>1)的升序序列S&#xff0c;处在第[L/2]个位置的数称为S的中位数。例如&#xff0c;若序列S1{11,13,15,17,19},则S1的中位数是15&#xff0c;两个序列的中位数是含它们所有元素的升序序列的中位数&#xff0c;例如…

使用ida pro反编译并修改so库

快速搜索 图表视图 找到需要修改的行 Edit -> Patch program -> change byte… 复制指令 到这个网站Online ARM to HEX 点击可以切换为HEX to ARM 构造待修改的指令 修改好后复制HEX字符串 Edit -> Patch program -> Apply patches to input file

测试工程师的个人年终总结报告模板

目录 正文之前的思考&#xff1a; 年终总结报告 开篇语 1.  项目概述 1.1  项目情况 1.2  工作流程 1.3  个人角色 1.4  完成情况 2.  工作业绩 3.  亮点和不足 4.  未来展望 总结&#xff1a; 正文之前的思考&#xff1a; 开始编排文档之前来做一个…

FAM NHS ester,5-FAM azide,两者用于标记核苷酸的荧光试剂

一、FAM NHS ester,6-isomer&#xff0c;92557-81-8 理论分析&#xff1a; 中文名&#xff1a;羧基荧光素-活性酯&#xff0c;6-异构体&#xff0c;6-羧基荧光素琥珀酰亚胺酯,6-羧基荧光素-活性酯 英文名&#xff1a;FAM NHS ester,6-isomer&#xff0c;6-FAM-NHS&#xff0c;…

D. Survey in Class

D. Survey in Class Problem - D - Codeforces 思路&#xff1a;题目要求的是最大值与最小值的差值最大&#xff0c;那么我们能够想到&#xff0c;一定是两个人比较得到的最大的差值&#xff0c;假设a与b比较得到的最大的差值&#xff0c;因为如果提问了这两个区间都不包含的&…

单个电源模块带电感的直流压降仿真(二)

单个电源模块带电感的直流压降仿真(二) 接 单个电源模块带电感的直流压降仿真(一) 在右侧net manager disable all nets鼠标移动到需要仿真的电感前后两端的铜皮上,select net and enable net并且把GND也select和enable上

ceph用户认证

Cephx认证机制 ceph使用cephx协议对客户端进行身份认证 cephx用于对ceph保存的数据进行认证访问和授权&#xff0c;用于对访问ceph的请求进行认证和授权检测&#xff0c;于mon通信的请求都要经过ceph认证通过&#xff0c;但是也可以在mon节点关闭cephx认证&#xff0c;但是关…