Elasticsearch 高级

news2025/4/1 19:13:07

Elasticsearch 高级

建议阅读顺序:

  1. Elasticsearch 入门
  2. Elasticsearch 搜索
  3. Elasticsearch 搜索高级
  4. Elasticsearch高级(本文)

1. nested 类型

1.1 介绍

Elasticsearch 中的 nested 类型允许你在文档内存储复杂的数据结构,比如一个用户可能有多个地址,或者一个博客文章可能有多个标签等。nested 类型可以让你索引这些复杂数据,并且允许你对嵌套的数据进行查询。

1.2 添加 nested 文档

向商品映射中添加 nested 类型的字段 attr_list

  • attr_list 表示商品属性
  • attr_list 有两个字段:color、memory
PUT /items/_mapping
{
  "properties":{
    "attr_list":{
      "type":"nested",
      "properties":{
        "name":{ "type":"keyword" },
        "value":{ "type":"keyword" }
      }
    }
  }
}

由于添加了字段,所以需要对 items 索引进行更新,但是建议先删后加:

DELETE /items
PUT /items
{
  "mappings" : {
    "properties" : {
      "brand" : { "type" : "keyword" },
      "category" : { "type" : "keyword" },
      "commentCount" : { "type" : "integer", "index" : false },
      "id" : { "type" : "keyword" },
      "image" : { "type" : "keyword", "index" : false },
      "isAD" : { "type" : "boolean" },
      "name" : {
        "type" : "text",
        "analyzer" : "ik_max_word",
        "search_analyzer" : "ik_smart"
      },
      "price" : { "type" : "integer" },
      "sold" : { "type" : "integer" },
      "stock" : { "type" : "integer" },
      "updateTime" : { "type" : "date" },
      "location" : { "type" : "geo_point" },
      "attr_list":{
        "type":"nested",
        "properties":{
          "name":{ "type":"keyword" },
          "value":{ "type":"keyword" }
        }
      }
    }
  }
}

在实体类上添加属性:

// 商品属性
@ApiModelProperty("商品规格")
private List<Spec> attr_list;

@Data
public static class Spec {
  private String name;
  private String value;
}

向索引添加文档,可以添加单个文档也可以批量添加文档,添加文档时指定商品属性:

@Test
void testAddDocument2() throws Exception {
  // 商品id
  Long id = 317578L;
  // 根据id查询商品
  Item item = itemService.getById(id);

  // 转为ItemDoc
  ItemDoc itemDoc = BeanUtils.copyBean(item, ItemDoc.class);
  ItemDoc.Spec spec_1 = new ItemDoc.Spec();
  spec_1.setName("大小");
  spec_1.setValue("60*40");
  // 再设置一个新规格
  ItemDoc.Spec spec_2 = new ItemDoc.Spec();
  spec_2.setName("颜色");
  spec_2.setValue("白色");
  itemDoc.setAttr_list(List.of(spec_1, spec_2));

  // 使用esClient添加文档
  IndexResponse response = esClient.index(
    i -> i.index("items").id(id.toString()).document(itemDoc)
  );

  // 打印结果
  String s = response.result().jsonValue();
  log.info("添加文档结果:{}", s);
}

查询文档:GET /items/_doc/{id}

1.3 搜索 nested

查询商品颜色是白色的商品:

GET /items/_search
{
  "query": {
    "nested": {
      "path": "attr_list",
      "query": {
        "bool": {
          "must": [
            { "term": { "attr_list.name": { "value": "颜色" } } },
            { "term": { "attr_list.value": { "value": "白色" } } }
          ]
        }
      }
    }
  }
}

"nested":这是一个嵌套查询,用于查询嵌套对象。它允许你在嵌套对象中执行更复杂的查询。

"path": "attr_list":指定了要查询哪个嵌套对象字段。在这个例子中,嵌套对象的字段名是attr_list

1.4 聚合 nested

先按商品属性名称聚合,再按属性值聚合:

GET /items/_search
{
  "size": 0,
  "aggs": {
    "attr_aggs": {
      "nested": { "path": "attr_list" },
      "aggs": {
        "attr_name_aggs": {
          "terms": { "field": "attr_list.name", "size": 10 },
          "aggs": {
            "attr_value_aggs": {
              "terms": { "field": "attr_list.value", "size": 10 }
            }
          }
        }
      }
    }
  }
}

1.5 Java Client

1.5.1 nested 查询

将 “查询商品颜色是白色的商品” 的 DSL 转为对应代码:

@Test
void testNested() throws Exception {
  SearchRequest.Builder builder = new SearchRequest.Builder();
  builder.index("items");

  builder.query(
    q -> q.nested(
      n -> n.path("attr_list").query(
        q1 -> q1.bool(
          b -> b.must(
            a -> a.term(
              t -> t.field("attr_list.name").value("颜色")
            )
          ).must(
            a1 -> a1.term(
              t -> t.field("attr_list.value").value("白色")
            )
          )
        )
      )
    )
  );
  SearchRequest build = builder.build();
  SearchResponse<ItemDoc> response = esClient.search(build, ItemDoc.class);
  // 解析结果
  List<Hit<ItemDoc>> hits = response.hits().hits();
  hits.forEach(hit -> {
    ItemDoc source = hit.source();
    log.info("查询结果:{}", source);
  });
}
1.5.2 nested 聚合

将 “先按商品属性名称聚合,再按属性值聚合” 的 DSL 转为对应代码:

@Test
void testNestedAggs() throws Exception {

  SearchRequest.Builder builder = new SearchRequest.Builder();
  builder.index("items2");
  builder.size(0);
  builder.aggregations(
    "attr_aggs", 
    a -> a.nested(
      n -> n.path("attr_list")
    ).aggregations(
      "attr_name_aggs", 
      a1 -> a1.terms(
        t -> t.field("attr_list.name").size(10)
      ).aggregations(
        "attr_value_aggs", 
        a2 -> a2.terms(
          t -> t.field("attr_list.value")
        )
      )
    )
  );
  SearchRequest build = builder.build();
  SearchResponse<ItemDoc> response = esClient.search(build, ItemDoc.class);
  Map<String, Aggregate> aggregations = response.aggregations();
  Aggregate attrAggs = aggregations.get("attr_aggs");
  //解析结果
  NestedAggregate nested = attrAggs.nested();
  Map<String, Aggregate> attrNameAggs = nested.aggregations();
  Aggregate aggregate = attrNameAggs.get("attr_name_aggs");

  aggregate.sterms().buckets().array().forEach(bucket -> {
    String key = bucket.key().stringValue();
    Long docCount = bucket.docCount();
    log.info("属性名:{},属性值数量:{}", key, docCount);
    Map<String, Aggregate> aggregations1 = bucket.aggregations();
    Aggregate attrValueAggs = aggregations1.get("attr_value_aggs");
    attrValueAggs.sterms().buckets().array().forEach(bucket1 -> {
      String key1 = bucket1.key().stringValue();
      Long docCount1 = bucket1.docCount();
      log.info("属性值:{},属性值数量:{}", key1, docCount1);
    });
  });
}

2. 同义词

2.1 设置同义词

搜索中同义词的需求:在搜索时输入一个关键字,包含关键字同义词的文档应该也可以搜索出来。

比如:输入“电脑”,会搜索出包含 “计算机” 的文档,输入 “黑马” 搜索出 “黑马程序员”、“传智播客” 的文章。

elasticsearch 的同义词有如下两种形式:

  1. 单向同义词:

    heima,黑马=>黑马程序员,黑马、传智播客
    

    箭头左侧的词都会映射成箭头右侧的词。

    输入箭头左侧的词可以搜索出箭头右侧的词。

  2. 双向同义词:

    马铃薯, 土豆, potato
    

    双向同义词可以互相映射。

    输入 “土豆” 可以搜索出 “potato”,输入 “potato” 可以搜索出 “土豆”

怎么设置同义词?

首先在同义词加到 synonyms.txt 文件中,synonyms.txt 文件在 es 的 config 目录下。

在 synonyms.txt 中加入:

中国,中华人民共和国,china
heima,黑马=>黑马程序员,黑马、传智播客
...

2.2 定义同义词分词器

在设置索引映射时自定义同义词分词器 my_synonyms_analyzer,并且用于 “title” 字段的搜索。

PUT /test_index
{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "updateable": true,
          "synonyms_path": "synonyms.txt"
        }
      },
      "analyzer": {
        "my_synonyms_analyzer": {
          "tokenizer": "ik_smart",
          "filter": [ "my_synonym_filter" ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "my_synonyms_analyzer"
      }
    }
  }
}

参数说明:

  • my_synonym_filter 是自定义的词汇过滤器
  • my_synonyms_analyzer 是自定义的分析器,my_synonyms_analyzer 包含并引用了 my_synonym_filter
  • updateable 指示能否动态更新,必须为 true 才能动态更新同义词;
  • synonyms_path 指示同义词文件的位置;
  • my_synonyms_analyzer 分析器里用 ik_smart 的分词器,my_synonyms_analyzer 的分词流程是原始文本先经过 ik_smart 分词的结果再用 my_synonym_filter 处理;
  • mappings.properties.title.search_analyzer 指示 title 字段在搜索时使用 my_synonyms_analyzer 分析器。

2.3 测试

先向 test_index 索引中添加数据:

POST /_bulk
{"index": {"_index":"test_index", "_id": "5"}}
{"title": "china你好"}
{"index": {"_index":"test_index", "_id": "4"}}
{"title": "中国你好"}
{"index": {"_index":"test_index", "_id": "6"}}
{"title": "中华人民共和国你好"}
{"index": {"_index":"test_index", "_id": "7"}}
{"title": "China你好"}
{"index": {"_index":"test_index", "_id": "8"}}
{"title": "这是一匹黑马"}
{"index": {"_index":"test_index", "_id": "9"}}
{"title": "黑马是中国良心培训机构"}
{"index": {"_index":"test_index", "_id": "10"}}
{"title": "黑马程序员是中国良心培训机构"}
{"index": {"_index":"test_index", "_id": "11"}}
{"title": "传智播客一所IT培训机构"}

搜索关键字 “china”:

GET /test_index/_search
{
  "query": {
    "match": { "title": "china" }
  }
}

分析查询到的结果,会发现,查询到的结果只有包含关键字的值,很显然同义词并没有生效,此时就要开启同义词生效,执行 POST /test_index/_reload_search_analyzers

3. 自动补全

3.1 介绍

当在搜索框输入字符时提示出与该字符有关的搜索项,这个效果就是自动补全。

Elasticsearch 如何实现自动补全?

要实现上述自动补全的需求需要完成两个功能:

  1. 拼音搜索
  2. 前缀搜索

3.2 拼音分词器

3.2.1 安装拼音分词器

与 IK 分词器一样,拼音分词器也有插件,在 GitHub 上有 elasticsearch 的拼音分词插件。

地址:https://github.com/medcl/elasticsearch-analysis-pinyin

找到与 Elasticsearch 版本一致的插件下载包。

安装方式与IK分词器一样,分三步:

  1. 解压 elasticsearch-analysis-pinyin-7.17.7.zip
  2. 上传到虚拟机中 elasticsearch 的 plugin 目录
  3. 重启 elasticsearch
  4. 测试

测试

POST /_analyze
{
  "text": "黑马程序员",
  "analyzer": "pinyin"
}
3.2.2 自定义分词器

默认的拼音分词器会将每个汉字单独分为拼音,而我们希望的是每个词条形成一组拼音,需要对拼音分词器做个性化定制,形成自定义分词器。

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

  1. character filters:在 tokenizer 之前对文本进行处理。例如删除字符、替换字符
  2. tokenizer:将文本按照一定的规则切割成词条(term)。例如 keyword,就是不分词;还有 ik_smart
  3. tokenizer filter:将 tokenizer 输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等

声明自定义分词器的语法如下:

PUT /test_index2
{
  "settings": {
    "analysis": {
      // 自定义分词器
      "analyzer": {
        // 分词器名称
        "my_analyzer": { "tokenizer": "ik_max_word", "filter": "py" }
      },
      // 自定义tokenizer filter
      "filter": {
        // 过滤器名称
        "py": {
          // 过滤器类型,这里是pinyin
          "type": "pinyin",
          "keep_full_pinyin": true,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

属性说明:

  1. type: "pinyin"

    这指定了过滤器的类型为 pinyin,即使用拼音分词器。

  2. keep_full_pinyin: false

    控制是否保留完整的拼音形式。设置为 false 表示不保留完整的拼音形式。

  3. keep_joined_full_pinyin: true

    控制是否保留连接的完整拼音形式。设置为 true 表示保留连接的完整拼音形式,例如 “你好” 可能会被转换为 “nihao”。

  4. keep_original: true

    控制是否保留原文本。设置为 true 表示保留原文本,这在某些情况下很有用,例如需要同时支持拼音和原文本的搜索。

  5. limit_first_letter_length: 16

    控制首字母的最大长度。例如,“你好” 的首字母形式为 “n h”,这个值控制了首字母的最大长度。

  6. remove_duplicated_term: true

    控制是否移除重复的词条。设置为 true 表示移除重复的词条,这有助于减少索引大小。

  7. none_chinese_pinyin_tokenize: false

    控制是否对非中文文本也进行拼音分词。设置为 false 表示不对非中文文本进行拼音分词。

测试自定义分词器:

POST /test_index2/_analyze
{
  "text": "黑马程序员",
  "analyzer": "my_analyzer"
}

3.3 自动补全查询

3.3.1 completion

Elasticsearch 专门设计 completion 查询用于自动补全,completion 查询可以实现前缀搜索的效果,性能比前缀搜索更快。

completion 查询会匹配以用户输入内容开头的词条并返回,使用 completion 查询对文档中字段的类型有一些约束:

  • 参与补全查询的字段必须是 completion 类型。
  • 字段的内容一般是用来补全的多个词条形成的数组。

在 test_index2 索引中添加 suggestion 字段并且设置为 completion 类型:

PUT /test_index2/_mapping
{
  "properties": {
    "suggestion": { "type":"completion" }
  }
}
3.3.2 测试

更新原有文档,文档中指定了自动补全的内容:

POST /test_index2/_update/100
{
  "doc": { "suggestion": ["拉杆箱","托运箱"] }
}


POST /test_index2/_update/101
{
  "doc": { "suggestion": ["拉杆箱","旅行箱","莎米特"] }
}

测试:

GET /test_index2/_search
{
  "suggest" : {
    "suggestion_suggest" : {  
      "completion" : { 
        "field": "suggestion",  
        "size": 10,  
        "skip_duplicates": true  
      },
      "text" : "旅"  
    }
  }
}

参数说明:

  1. suggest:这是建议器的顶级对象,用于配置建议器。

  2. suggestion_suggest:这是建议器的名称,可以自定义。它用于标识建议器。

  3. completion

    这是指定建议器类型的部分。在这里,我们使用的是 completion 类型,它是专门为自动补全设计的建议器。

  4. field

    这是用于建议的字段名称。在这个例子中,我们使用名为 suggestion 的字段,该字段应该已经被配置为completion类型的字段。

  5. size

    这个参数控制返回的建议数量。在这个例子中,我们设置了 size 为10,意味着最多返回10个建议。

  6. skip_duplicates

    这个参数用于控制是否在返回的建议中跳过重复的条目。在这个例子中,我们设置为 true,意味着如果某个建议在多个文档中出现,只会返回一次。

  7. text:这是用户输入的文本,用于生成建议。

3.3.3 Java Client
@Test
void testSuggest() throws IOException {
  SearchRequest.Builder builder = new SearchRequest.Builder();
  builder.index("test_index2");
  builder.suggest(
    s -> s.suggesters(
      "suggestion_suggest", 
      ss -> ss.completion(
        c -> c.field("suggestion").size(10).skipDuplicates(true)
      ).text("拉")
    )
  );
  SearchRequest request = builder.build();
  SearchResponse<Index2> response = esClient.search(request, Index2.class);
  Map<String, List<Suggestion<Index2>>> suggest = response.suggest();
  List<Suggestion<Index2>> suggestion_suggest = suggest.get("suggestion_suggest");
  suggestion_suggest.stream().forEach(suggestion -> {
    suggestion.completion().options().forEach(option -> {
      String text = option.text();
      System.out.println(text);
    });
  });
}

/**
  * 测试自动补全模型类
  */
@Data
public static class Index2 {
  //id
  private Long id;
  //name
  private String name;
  private List<String> suggestion;

}

3.4 拼音自动补全

3.4.1 创建自动补全字段

自定义分词器:

PUT /test_index3
{
  "settings": {
    "analysis": {
      "analyzer": {
        "completion_analyzer": { "tokenizer": "keyword", "filter": "py" }
      },
      "filter": {
        "py": {
          "type": "pinyin",
          "keep_full_pinyin": true,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id": { "type": "keyword" },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "suggestion":{ "type": "completion", "analyzer": "completion_analyzer" }
    }
  }
}
3.4.2 更新/新增文档
POST test_index3/_doc/100
{
  "id":100,
  "name":"RIMOWA 30寸托运箱拉杆箱 SALSA AIR系列果绿色 820.70.36.4",
  "suggestion": ["拉杆箱","托运箱"]
}


POST test_index3/_doc/101
{
  "id":101,
  "name":"莎米特SUMMIT 旅行拉杆箱28英寸PC材质大容量旅行行李箱PC154 黑色",
  "suggestion": ["拉杆箱","旅行箱","莎米特"]
}

POST test_index3/_doc/102
{
  "id":102,
  "name":"拉菲斯汀(La Festin)612026 新款女士钱包 头层牛皮短款钱包 凯利黑",
  "suggestion": ["拉菲斯汀","女包"]
}
3.4.3 测试
GET /test_index3/_search
{
  "suggest": {
    "suggestion_suggest": {
      "completion": {
        "field": "suggestion",
        "size": 2,
        "skip_duplicates": true
      },
      "text": "la"
    }
  }
}

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

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

相关文章

C语言笔记数据结构(链表)

希望文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正,一起交流学习! 目录 1.链表 1.1 链表概念和组成 1.2 链表的分类 1.3 顺序表和链表 2.单链表&#xff08;无头单向不循环链表&#xff09; 2.1 结点的创建 2.2 创建新的结点 2.3 单链表的打印 2.4 尾…

Leetcode 两数相除

✅ LeetCode 29. 两数相除 — 思路总览 &#x1f9e9; 题目要求 给定两个整数 dividend 和 divisor&#xff0c;实现 整数除法&#xff0c;不能使用乘法 *、除法 / 和取余 % 运算符。 要求返回的结果应为 向零截断的整数商&#xff0c;即&#xff1a; 正数向下取整&#xf…

人工智能图像识别Scala介绍

Scala 一.Scala 简介 Scala即Scalable Language&#xff08;可伸缩的语言&#xff09;&#xff0c;Scala 语言是由 Martin Odersky 等人在 2003 年开发的&#xff0c;并于 2004 年首次发布。意味着这种语言设计上支持大规模软件开发&#xff0c;是一门多范式的编程语言。 Sc…

C++中使用CopyFromRecordset将记录集拷贝到excel中时,如果记录集为0个,函数崩溃,是什么原因

文章目录 原因分析解决方案1. 检查记录集是否为空2. 安全调用COM方法3.进行异常捕获4. 替代方案&#xff1a;手动处理空数据 总结 在C中使用CopyFromRecordset将空记录集&#xff08;0条记录&#xff09;复制到Excel时崩溃的原因及解决方法如下&#xff1a; 原因分析 空记录集…

c#的.Net Framework 的console 项目找不到System.Window.Forms 引用

首先确保是建立的.Net Framework 的console 项目,然后天健reference 应用找不到System.Windows.Forms 引用 打开对应的csproj 文件 在第一个PropertyGroup下添加 <UseWindowsForms>true</UseWindowsForms> 然后在第一个ItemGroup 下添加 <Reference Incl…

蓝桥杯嵌入式学习笔记

用博客来记录一下参加蓝桥杯嵌入式第十六届省赛的学习经历 工具环境准备cubemx配置外部高速时钟使能设置串口时钟配置项目配置 keil配置烧录方式注意代码规范头文件配置 模块ledcubemx配置keil代码实现点亮一只灯实现具体操作的灯&#xff0c;以及点亮还是熄灭 按键cubemx配置k…

Blender多摄像机怎么指定相机渲染图像

如题目所说&#xff0c;当blender的场景里面有摄像机的时候&#xff0c;按F12可以预览渲染结果&#xff0c;但是当有多个摄像机的时候就不知道使用哪个进行渲染了。 之前在网上没有找到方法&#xff0c;就用笨方法&#xff0c;把所有的摄像机删除&#xff0c;然后设置自己需要…

从 MySQL 到时序数据库 TDengine:Zendure 如何实现高效储能数据管理?

小T导读&#xff1a;TDengine 助力广州疆海科技有限公司高效完成储能业务的数据分析任务&#xff0c;轻松应对海量功率、电能及输入输出数据的实时统计与分析&#xff0c;并以接近 1 : 20 的数据文件压缩率大幅降低存储成本。此外&#xff0c;taosX 强大的 transform 功能帮助用…

观察者模式:解耦对象间的依赖关系

观察者模式&#xff1a;解耦对象间的依赖关系 JDK 中曾直接提供对观察者模式的支持&#xff0c;但因其设计局限性&#xff0c;现已被标记为“过时”&#xff08;Deprecated&#xff09;。不过&#xff0c;观察者模式的思想在 JDK 的事件处理、spring框架等仍有广泛应用。下面我…

windows第二十章 单文档应用程序

文章目录 单文档定义新建一个单文档应用程序单文档应用程序组成&#xff1a;APP应用程序类框架类&#xff08;窗口类&#xff09;视图类&#xff08;窗口类&#xff0c;属于框架的子窗口&#xff09;文档类&#xff08;对数据进行保存读取操作&#xff09; 直接用向导创建单文档…

通信协议之串口

文章目录 简介电平标准串口参数及时序USART与UART过程引脚配置 简介 点对点&#xff0c;只能两设备通信只需单向的数据传输时&#xff0c;可以只接一根通信线当电平标准不一致时&#xff0c;需要加电平转换芯片&#xff08;一般从控制器出来的是信号是TTL电平&#xff09;地位…

Java入门知识总结——章节(二)

ps&#xff1a;本章主要讲数组、二维数组、变量 一、数组 数组是一个数据容器&#xff0c;可用来存储一批同类型的数据 &#x1f511;&#xff1a;注意 类也可以是一个类的数组 public class Main {public static class Student {String name;int age; // 移除 unsignedint…

Verilog 中寄存器类型(reg)与线网类型(wire)的区别

目录 一、前言 二、基本概念与分类 1.寄存器类型 2.线网类型 三、六大核心区别对比 四、使用场景深度解析 1.寄存器类型的典型应用 2. 线网类型的典型应用 五、常见误区与注意事项 1. 寄存器≠物理寄存器 2.未初始化值陷阱 3.SystemVerilog的改进 六、总结 …

【Linux加餐-验证UDP:TCP】-windows作为client访问Linux

一、验证UDP-windows作为client访问Linux UDP client样例代码 #include <iostream> #include <cstdio> #include <thread> #include <string> #include <cstdlib> #include <WinSock2.h> #include <Windows.h>#pragma warning(dis…

Rust vs. Go: 性能测试(2025)

本内容是对知名性能评测博主 Anton Putra Rust vs. Go (Golang): Performance 2025 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。 再次对比 Rust 和 Go&#xff0c;但这次我们使用的是最具性能优势的 HTTP 服务器库---Hyper&#xff0c;它基于 Tokio 异步运…

JDBC的详细使用

1. JDBC概述 JDBC[Java Database Connectivity]是 Java 语言中用于连接和操作数据库的一套标准 API。它允许 Java 程序通过统一的方式与各种关系型数据库&#xff0c;如 MySQL、Oracle、SQL Server 等交互&#xff0c;执行 SQL 语句并处理结果。 1.1 JDBC原理 JDBC的核心原理…

瑞芯微 RKrga接口 wrapbuffer_virtualaddr 使用笔记

一、源码 官方在librga中给了很多 demo 以供参考&#xff0c;例如 imresize 操作&#xff1a; /** Copyright (C) 2022 Rockchip Electronics Co., Ltd.* Authors:* YuQiaowei <cerf.yurock-chips.com>** Licensed under the Apache License, Version 2.0 (the &qu…

【数据结构】[特殊字符] 并查集优化全解:从链式退化到近O(1)的性能飞跃 | 路径压缩与合并策略深度实战

并查集的优化 导读一、合并优化1.1 基本原理1.2 按大小合并1.3 按秩合并1.4 两种合并的区别**1.4.1 核心目标****1.4.2 数据存储****1.4.3 合并逻辑****1.4.4 树高控制****1.4.5 适用场景****1.4.6 路径压缩兼容性****1.4.7 极端案例对比****1.4.8 小结**二、查找优化2.1 路径压…

如何在 AI 搜索引擎(GEO)霸屏曝光,快速提升知名度?

虽然大多数人仍然使用 Google 来寻找答案&#xff0c;但正在发生快速转变。ChatGPT、Copilot、Perplexity 和 DeepSeek 等 LLM 已成为主流。这主要是因为每个都有自己的免费和公共版本&#xff0c;并且总是有重大的质量改进。 许多人每天都使用这些工具来提问和搜索互联网&…

VLAN综合实验二

一.实验拓扑&#xff1a; 二.实验需求&#xff1a; 1.内网Ip地址使用172.16.0.0/分配 2.sw1和SW2之间互为备份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通过DHCP获取IP地址 5.ISP只能配置IP地址 6.所有…