Elasticsearch:构建自定义分析器指南

在本博客中,我们将介绍不同的内置字符过滤器、分词器和分词过滤器,以及如何创建适合我们需求的自定义分析器。更多关于分析器的知识,请详细阅读文章:

  • 开始使用 Elasticsearch (3)

  • Elasticsearch: analyzer

为什么我们需要定制分析器?

你可以通过以所需的方式组合字符过滤器、分词器和分词过滤器来创建自定义分析器来满足您的特定需求。 这使得文本处理具有高度的灵活性和定制性。

正如我们所见,Elasticsearch 中的分析器由三部分组成,我们将看到不同的内置组件:

安装

为了方便今天的测试,我们将安装无安全配置的 Elasticsearch 及 Kibana。我们可以参考文章 “Elasticsearch:如何在 Docker 上运行 Elasticsearch 8.x 进行本地开发”。

我们还需要安装 Python 所需要的包:

pip3 install elasticsearch
$ pip3 list | grep elasticsearch
elasticsearch                            8.12.0
rag-elasticsearch                        0.0.1        /Users/liuxg/python/rag-elasticsearch/my-app/packages/rag-elasticsearch

测试

我们创建一个连接到 Elasticsearch 的客户端:

from elasticsearch import Elasticsearch

es = Elasticsearch("http://localhost:9200")
print(es.info())

更多关于如何连接到 Elasticsearch 的代码,请参考 “Elasticsearch:关于在 Python 中使用 Elasticsearch 你需要知道的一切 - 8.x”。

Char map filters

HTML Strip Char Filter (html_strip)

从文本中删除 HTML 元素并解码 HTML 实体。

response = es.indices.analyze(
    body={
        "char_filter": ["html_strip"],
        "tokenizer": "standard",
        "text": "<p>Hello <b>World</b>! This is <a href='<http://example.com>'>Elasticsearch</a>.</p>"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Pattern Replace Char Filter (pattern_replace)

使用正则表达式来匹配字符或字符序列并替换它们。 在下面的示例中,我们从用户名中提取名称:

response = es.indices.analyze(
    body={
        "char_filter": [
            {
                "type": "pattern_replace",
                "pattern": "[-_@.]",  # Removes hyphens, underscores, apostrophes
                "replacement": " "
            }
        ],
        "tokenizer": "standard",
        "text": "liu_xiao_guo"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Mapping Char Filter (mapping)

允许自定义定义的字符或字符序列映射。 示例:你可以定义一个映射,将 “&” 替换为 “and”,或将 “€” 替换为 “euro”。

response = es.indices.analyze(
    body={
        "tokenizer": "standard",
        "char_filter": [
            {
                "type": "mapping",
                "mappings": [
                    "@gmail.com=>",    # Replace @gmail.com with nothing
                    "$=>dollar",       # Replace $ with dollar
                ]
            }
        ],
        "text": "xiaoguo.liu@gmail.com gives me $"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Tokenizers

Standard Tokenizer (standard)

Standard 分词器将文本按照单词边界划分为术语,如 Unicode 文本分段算法所定义。 它删除了大多数标点符号。 它是大多数语言的最佳选择。

response = es.indices.analyze(
    body={
        "tokenizer": "standard",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Letter Tokenizer (letter)

每当遇到非字母的字符时,letter 分词器就会将文本分成术语。

response = es.indices.analyze(
    body={
        "tokenizer": "letter",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Lowercase Tokenizer (lowercase)

小写分词器类似于字母分词器,但它也将所有术语小写。

response = es.indices.analyze(
    body={
        "tokenizer": "lowercase",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Whitespace Tokenizer (whitespace)

每当遇到任何空白字符时,whitespace 分词器都会将文本划分为术语。

response = es.indices.analyze(
    body={
        "tokenizer": "whitespace",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Classic Tokenizer (classic)

classic 分词器是一种基于语法的英语分词器。

response = es.indices.analyze(
    body={
        "tokenizer": "classic",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

UAX URL Email Tokenizer (uax_url_email)

uax_url_email 标记生成器类似于标准标记生成器,只不过它将 URL 和电子邮件地址识别为单个标记。

response = es.indices.analyze(
    body={
        "tokenizer": "classic",
        "text": "visit https://elasticstack.blog.csdn.net to get the best materials to learn Elastic Stack"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

N-Gram Tokenizer (ngram)

当 ngram 分词器遇到任何指定字符(例如空格或标点符号)列表时,它可以将文本分解为单词,然后返回每个单词的 n-grams:连续字母的滑动窗口,例如 Quick → [qu, ui, ic, ck]。Elasticsearch 中的 N-Gram 分词器在术语部分匹配很重要的场景中特别有用。 最适合自动完成和键入时搜索功能以及处理拼写错误或匹配单词中的子字符串。

response = es.indices.analyze(
    body={
        "tokenizer": {
            "type": "ngram",
            "min_gram": 3,
            "max_gram": 4
        },
        "text": "Hello Xiaoguo"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Edge N-Gram Tokenizer (edge_ngram)

Elasticsearch 中的 edge_ngram 分词器用于从单词的开头或 “边缘” 开始将单词分解为更小的块或 “n-gram”。 它生成指定长度范围的标记,提供单词从开头到给定大小的一部分。

response = es.indices.analyze(
    body={
        "tokenizer": {
                "type": "edge_ngram",
                "min_gram": 4,
                "max_gram": 5,
                "token_chars": ["letter", "digit"]
        },
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Keyword Tokenizer (keyword)

关键字分词器接受给定的任何文本,并将完全相同的文本输出为单个术语。

response = es.indices.analyze(
    body={
        "tokenizer": "keyword",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Pattern Tokenizer (pattern)

Pattern 分词器使用正则表达式,在文本与单词分隔符匹配时将其拆分为术语,或者将匹配的文本捕获为术语。

response = es.indices.analyze(
    body={
        "tokenizer": {
          "type": "pattern",
          "pattern": "_+"
        },
        "text": "hello_world_from_elasticsearch"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Path Tokenizer (path_hierarchy)

它将路径在每个路径分隔符处分解为分词。

response = es.indices.analyze(
    body={
        "tokenizer": "path_hierarchy",
        "text": "/usr/local/bin/python"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Token filters

确保你始终传递列表中的过滤器,即使它只有一个,并且你应用的过滤器的顺序非常重要。

Apostrophe

删除撇号后面的所有字符,包括撇号本身。

response = es.indices.analyze(
    body={
        "filter": ["apostrophe"],
        "tokenizer": "standard",
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Lowercase Filter

将所有分词转换为小写。

response = es.indices.analyze(
    body={
        "filter": ["lowercase"],
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Uppercase Filter

将所有分词转换为大写。

response = es.indices.analyze(
    body={
        "filter": ["uppercase"],
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Trim Filter

删除流中每个分词的前导和尾随空格。

# Analyze the text using the custom analyzer
response = es.indices.analyze(
    body={
        "tokenizer": "keyword",
        "filter":[
            "lowercase",
            "trim"
         ],
        "text": " The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone. "
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

ASCII Folding Filter (asciifolding)

asciifolding 过滤器会删除标记中的变音标记。比如,Türkiye 将成为 Turkiye。

# Analyze the text using the custom analyzer
response = es.indices.analyze(
    body={
        "filter": ["asciifolding"],
        "text": "Türkiye"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Synonym Filter

synonym 分词过滤器允许在分析过程中轻松处理同义词。

# Analyze the text using the custom analyzer
response = es.indices.analyze(
    body={
        "tokenizer": "standard",
        "filter":[
            "lowercase",
            {
              "type": "synonym",
              "synonyms": ["jumps_over => leap"]
            }
         ],
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Synonym Graph Filter

最适合多词同义词。

response = es.indices.analyze(
    body={
        "tokenizer": "standard",
        "filter":[
            "lowercase",
            {
              "type": "synonym_graph",
              "synonyms": ["NYC, New York City", "LA, Los Angeles"]
            }
         ],
        "text": "Flight from LA to NYC has been delayed by an hour"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

请记住,输出并不直观地表示内部图形结构,但 Elasticsearch 在搜索查询期间使用此结构。

与通常同义词不匹配的匹配短语查询将与同义词图完美配合。

Stemmer Filter

词干过滤器,支持多种语言的词干提取。

response = es.indices.analyze(
    body={
    "tokenizer": "standard",
    "filter": [
        {
            "type": "stemmer",
            "language": "English",
        },
        ],
    "text": "candies, ladies, plays, playing, ran, running, dresses"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

KStem Filter

kstem 过滤器将算法词干提取与内置字典相结合。 与其他英语词干分析器(例如 porter_stem 过滤器)相比,kstem 过滤器的词干提取力度较小。

response = es.indices.analyze(
    body={
 "tokenizer": "standard",
 "filter": [
    'kstem',
  ],
 "text": "candies, ladies, plays, playing, ran, running"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Porter Stem Filter

与其他英语词干过滤器(例如 kstem 过滤器)相比,倾向于更积极地进行词干提取。

response = es.indices.analyze(
    body={
    "tokenizer": "whitespace",
    "filter": [
        {
            "type": "pattern_replace",
            "pattern": "[-|.|,]"
        },
        {
            "type": "porter_stem",
            "language": "English",
        },
        ],
    "text": "candies, ladies, plays, playing, ran, running, dresses"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Snowball Filter

使用 Snowball 生成的词干分析器对单词进行词干分析的过滤器。 适用于法语、德语、俄语、西班牙语等不同语言。

response = es.indices.analyze(
    body={
    "tokenizer": "whitespace",
    "filter": [
        {
            "type": "snowball",
            "language": "English",
        },
        ],
    "text": "candies, ladies, plays, playing, ran, running, dresses"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Stemmer Override

通过应用自定义映射来覆盖词干算法,然后保护这些术语不被词干分析器修改。 必须放置在任何阻塞过滤器之前。

response = es.indices.analyze(
    body={
      "tokenizer": "standard",
      "filter": [
        {
            "type": "stemmer_override",
            "language": "English",
            "rules": [
                "running, runs => run",
                "stemmer => stemmer"
            ]
        },
        ],
      "text": "candies, ladies, plays, playing, ran, running, dresses"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

更多使用方法,请参考 Stemmer override token filter | Elasticsearch Guide [8.12] | Elastic

Keyword Marker Filter

将某些术语标记为关键字,防止它们被其他过滤器(如词干分析器)修改。

response = es.indices.analyze(
    body={
     "tokenizer": "whitespace",
     "filter": [
         {
            "type": "keyword_marker",
            "keywords": ["running"]  # Mark 'running' as a keyword
         },
         {
            "type": "pattern_replace",
            "pattern": "[-|.|,]"
         },
         {
            "type": "porter_stem",
            "language": "English",
         },
      ],
     "text": "candies, ladies, plays, playing, runs, running"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Stop Filter

从分词流中删除停用词(经常被忽略的常用词)。 示例 — if、of、is、am、are、the。可以使用默认或自定义的停用词列表。

# Analyze the text using the custom analyzer
response = es.indices.analyze(
    body={
        "tokenizer": "standard",
        "filter":{
            "type":"stop",
            "stopwords": ["is","am","are","of","if","a","the"],
            "ignore_case": True
        },
        "text": "i am sachin. I Am software engineer."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Unique Filter

从流中删除重复的分词。

response = es.indices.analyze(
    body={
     "tokenizer": "whitespace",
     "filter":[
         "lowercase", "unique",
      ],
     "text": "Happy happy joy joy"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Length Filter

删除比指定字符长度更短或更长的分词。

response = es.indices.analyze(
    body={
        "tokenizer": "standard",
        "filter":[
            "lowercase",
            {
              "type": "length",
              "min": 1,
              "max": 4
            }
         ],
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

NGram Token Filter

从分词形成指定长度的 ngram。 最适合在键入时自动完成或搜索。 或者用于用户可能会犯错或拼写错误的搜索。

response = es.indices.analyze(
    body={
     "tokenizer": "whitespace",
     "filter":[
         {
            "type": "ngram",
            "min_gram": 3,
            "max_gram": 4
         }
      ],
     "text": "Skinny blue jeans by levis"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Edge NGram Token Filter

从分词的开头形成指定长度的 ngram。 最适合在键入时自动完成或搜索。 它对于搜索建议中常见的部分单词匹配非常有效。

response = es.indices.analyze(
    body={
     "tokenizer": "whitespace",
     "filter":[
         {
            "type": "edge_ngram",
            "min_gram": 3,
            "max_gram": 4
         }
      ],
     "text": "Skinny blue jeans by levis"
    }
)

# Extract tokens
[token['token'] for token in response['tokens']]

Shingle Filter

通过连接相邻的标记,将 shingles 或单词 ngram 添加到分词流中。 默认情况下,shingle 分词过滤器输出两个字的 shingles。 最适用于提高搜索短语查询性能。

response = es.indices.analyze(
    body={
     "tokenizer": "whitespace",
     "filter":[
        {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 3           
        }
      ],
     "text": "Welcome to use Elastic Stack"
    }
)

[token['token'] for token in response['tokens']]

Creating a custom analyzer

以下是文本,下面是所需的输出:

text = "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."

# Desired output
['2', 'quick', 'brown', 'fox', 'jump', 'over', 'lazy', 'dog', 'bone']

分析器应完成的事情列表:

  • 删除所有符号 - 连字符和下划线。
  • 删除停用词。
  • 将所有文本小写。
  • 删除撇号。
  • 词干。
response = es.indices.analyze(
    body={
        "char_filter": [
            {
                "type": "mapping",
                "mappings": [
                    "- => ' '", # replacing hyphens with blank space
                    "_ => ' '", # replacing underscore with blank space
                 ]
            }
        ],
        "tokenizer": "standard",
        "filter": ["apostrophe", "lowercase", "stop", "porter_stem"],
        "text": "The 2 QUICK Brown-Foxes, jumps_over the lazy-dog's bone."
    }
)

# Extract and print tokens
tokens = [token['token'] for token in response['tokens']]
tokens

现在需要注意的一件事是顺序,无论你在内部处理时给 Elasticsearch 什么顺序,总是使用相同的顺序 char_filter > tokenizer > token_filter 但 char_filter 或 token filter 块内的顺序会有所不同。

将自定义分析器添加到索引

为了避免复杂化,最好创建一个新的索引并根据你的要求设置分析器。 以下是设置分析器的方法。

settings = {
    "settings": {
        "analysis": {
            "analyzer": {
                "my_custom_analyzer": {
                    "type": "custom",
                    "char_filter": {
                        "type": "mapping",
                        "mappings": [
                            "- => ' '",
                            "_ => ' '",
                        ]
                    },
                    "tokenizer": "standard",
                    "filter": ["lowercase", "apostrophe", "stop", "porter_stem"],
                }
            }
        },
        "index": {
            "number_of_shards": 1,
            "number_of_replicas": 0,
            "routing.allocation.include._tier_preference": "data_hot"
        },
    },
    "mappings": {
        "properties": {
            "title": {"type":"text", "analyzer":"my_custom_analyzer"},
            "brand": {"type": "text", "analyzer":"my_custom_analyzer", "fields": {"raw": {"type": "keyword"}}},
            "updated_time": {"type": "date"}
        }`
    }
}

response = es.indices.create(index="trial_index", body=index_settings)

你可以在地址找到所有的代码:https://github.com/liu-xiao-guo/analyzers-python

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Debezium发布历史101

原文地址&#xff1a; https://debezium.io/blog/2021/01/07/debezium-1-4-final-released/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. Debezium 1.4.0.Final 发布 2021 年 1 月 7 日 作者&#xff1a; 克里…

C#中的WebApi响应Accept头,自动返回xml或者json

Global.asax.cs中的Application_Start方法添加 GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new XmlMediaTypeFormatter()); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter())…

工作七年,对消息推送使用的一些经验和总结

前言&#xff1a;不管是APP还是WEB端都离不开消息推送&#xff0c;尤其是APP端&#xff0c;push消息&#xff0c;小信箱消息&#xff1b;WEB端的代办消息等。因在项目中多次使用消息推送且也是很多项目必不可少的组成部分&#xff0c;故此总结下供自己参考。 一、什么是消息推…

Vue.js 中子组件向父组件传值的方法

Vue.js 是一款流行的 JavaScript 前端框架&#xff0c;它提供了一套完整的工具和 API&#xff0c;使得开发者可以更加高效地构建交互式的 Web 应用程序。其中&#xff0c;组件化是 Vue.js 的一个核心概念&#xff0c;通过组件化可以将一个复杂的应用程序拆分成多个独立的部分&a…

3D应用开发平台HOOPS Platforms优化制造流程和数字化转型

Tech Soft 3D公司的HOOPS Platform &#xff08;包括HOOPS Native Platform 和HOOPS Web Platform&#xff09;&#xff0c;是一种用于开发顶级3D软件的集成技术。具有高性能3D图形&#xff0c;准确&#xff0c;快速的CAD数据转换&#xff0c;3D数据发布以及与流行的建模内核的…

iOS_Xcode_LLDB调试常用命令

文章目录 结构常用命令&#xff1a;1、流程控制&#xff1a;2、常用命令3、进程信息&#xff1a;4、寄存器&#xff1a;register5、镜像&#xff1a;image6、内存&#xff1a;memory7、符号断点&#xff1a;breakpoint8、内存断点&#xff1a;watchpoint9、Tips&#xff1a; 结…

音视频数字化(音频数字化)

在音视频领域,人们始终追求无限还原现场效果,因此音频越逼真越好,视频越清晰越好。之所以我们需要将音视频信号由模拟转为数字,目的是在录制、存储、编辑、复制、回放等环节的不失真,尽量保持原有细节,不因以上操作,导致音画的质量下降。 为此,视频系统分辨率越来越高,…

【iOS ARKit】手动配置环境探头

在上节中我们已经了解了环境探头以及如何使用自动环境探头&#xff0c;这节一起了解如何使用手动配置环境探头。 在使用自动环境反射时&#xff0c;开发人员无须进行有关环境反射的任何操作&#xff0c;只需要设置自动环境反射即可&#xff0c;其余工作完全由 RealityKit 自动完…

ArcGIS Pro字段编号相关代码

字段属于SHP文件的重要组成部分&#xff0c;在某些时候需要对字段进行编号&#xff0c;这里为大家介绍一下字段编号相关的代码&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数据&#xff0c;除了POI数据&#xff0c;常见的GIS数据都可…

全面掌握Django的web框架Django Rest_Framework(一)

文章目录 Django Rest_Framework1. DRF介绍2.DRF特点3.环境安装与配置&#xff08;1&#xff09;DRF需要以下依赖&#xff08;2&#xff09;创建django项目 4.序列化器的使用&#xff08;1&#xff09;创建序列化器 5. 反序列化器使用 Django Rest_Framework 1. DRF介绍 Djan…

springboot141夕阳红公寓管理系统的设计与实现

基于Spring Boot的夕阳红公寓管理系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的…

【爬虫专区】批量下载PDF (无反爬)

天命&#xff1a;只要没反爬&#xff0c;一切都简单 这次爬取的是绿盟的威胁情报的PDF 先看一下结构&#xff0c;很明显就是一个for循环渲染 burp抓包会发现第二次接口请求 接口请求一次就能获取到了所有的数据 然后一个循环批量下载数据即可&#xff0c;其实没啥难度的 imp…

使用Postman做API自动化测试

Postman最基本的功能用来重放请求&#xff0c;并且配合良好的response格式化工具。 高级点的用法可以使用Postman生成各个语言的脚本&#xff0c;还可以抓包&#xff0c;认证&#xff0c;传输文件。 仅仅做到这些还不能够满足一个系统的开发&#xff0c;或者说过于琐碎&#…

【鸿蒙】大模型对话应用(三):跨Ability跳转页面

Demo介绍 本demo对接阿里云和百度的大模型API&#xff0c;实现一个简单的对话应用。 DecEco Studio版本&#xff1a;DevEco Studio 3.1.1 Release HarmonyOS SDK版本&#xff1a;API9 关键点&#xff1a;ArkTS、ArkUI、UIAbility、网络http请求、列表布局、层叠布局 页面跳…

谷歌seo如何发布外链?

在谷歌SEO中发布外链就像是在网络世界中搭建桥梁&#xff0c;你需要在别人的网站里上精心放置通往你网站的路径&#xff0c;这种路径一般是单向的&#xff0c;可能只使用一次&#xff0c;但这依然是个需要花心思的工作 而对于谷歌seo的外链&#xff0c;很多人都会有一个误解&am…

pnpm : 无法加载文件 D:\tool\nvm\nvm\node_global\pnpm.ps1,因为在此系统上禁止运行脚本

你们好&#xff0c;我是金金金。 场景 新创建的项目&#xff0c;在vscode编辑器终端输入 pnpm i&#xff0c;显示报错如上 解决 在终端输入get-ExecutionPolicy(查看执行策略/权限) 输出Restricted(受限的) 终端再次输入Set-ExecutionPolicy -Scope CurrentUser命令给用户赋予…

Oracle篇—普通表迁移到分区表(第五篇,总共五篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

【乳腺肿瘤诊断分类及预测】基于PNN概率神经网络

课题名称&#xff1a;基于PNN的乳腺肿瘤诊断分类及预测 版本日期&#xff1a;2023-06-15 运行方式: 直接运行PNN0501.m 文件即可 代码获取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 威斯康辛大学医学院经过多年的收集和整理&#xff0c;建…

JAVASE进阶:内存原理剖析(1)——数组、方法、对象、this关键字的内存原理

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;首期文章 &#x1f4da;订阅专栏&#xff1a;JAVASE进阶 希望文章对你们有所帮助 技术栈我已经基本上是学完了的&#xff0c;这段…

LeetCode 828. 统计子串中的唯一字符

一开始想的是两次前缀和&#xff0c;发现自己蠢了 看了灵神的题解&#xff0c;类似于DP的思想 我们维护以每个字符串结尾的子字符串对答案的贡献&#xff0c;s[i]的贡献是多少&#xff1f;首先我们知道他需要自己单独一个串或者接在以s[i-1]结尾的那些字符串的后面&#xff0c…