ElasticSearch 全文检索相关性 算分

news2024/11/28 23:34:17

文章目录

  • 相关性
    • 相关性Relevance
    • 相关性算法
      • TF-IDF
      • BM25
    • 通过Explain查看TF-IDF
    • boosting query
  • 多字段查询 相关性
    • dis_max query最佳字段查询
    • multi_match query
      • best_fields最佳匹配字段
      • most_fields 多数字段搜索
      • cross_fields跨字段搜索

相关性

相关性Relevance

搜索的相关性算分,描述了一个文档和搜索的匹配程度,并对搜索结果按_score排序显示

衡量相关性的因素:

  • Precision(查准率):尽可能返回较少的无关文档
  • Recall(查全率):尽量返回较多的相关文档
  • Ranking:是否能够按照相关度进行排序



相关性算法

ES 5之前,默认的相关性算分采用TF-IDF,现在采用BM 25。

TF-IDF

ES5.X版本之前默认使用的相关性算法。

TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。

在这里插入图片描述



tf词频 Term Frequency

一个term词,在文档中出现的频率。检索词在文档中出现的频率越高,tf的值也就越高,最终计算出的相关性也越高。

tf词频 = 词在文档中出现频率 / 文档总词数



idf 逆向文本频率 inverse Document Frequency

检索词在索引中出现的频率,出现的频率越高,idf的值越低

# 避免分母为0 所以+1
idf逆向文本频率 = log(语料库的文档总数 / (包含该词的文档数+1))



norm字段长度归一值 field-length norm

检索词出现在一个内容短的文本中要比同样的词出现在内容长的文本中字段权重更大



BM25

BM25 就是对 TF-IDF 算法的改进,对于 TF-IDF 算法,TF(t) 部分的值越大,整个公式返回的值就会越大。BM25 就针对这点进行来优化,随着TF(t) 的逐步加大,该算法的返回值会趋于一个数值。

  • 从ES 5开始,默认算法改为BM 25
  • 和经典的TF-IDF相比,当TF无限增加时,BM 25算分会趋于一个数值

在这里插入图片描述

BM 25的公式

在这里插入图片描述



通过Explain查看TF-IDF

使用explain有两种方式,在url中添加_explain,或者是在请求体中添加explain: true

# 使用 "explain": true 查看
GET /sys_user/_search
{
  "explain": true,
  "query": {
    "match": {
      "address": "广州"
    }
  }
}

# 直接在url中添加_explain
GET /sys_user/_explain/1
{
  "query": {
    "match": {
      "address": "广州"
    }
  }
}

在这里插入图片描述



boosting query

boosting是控制相关度的一种手段,我们可以通过指定字段的boost值影响查询结果

  • boost > 1 相关性打分将会提高
  • 0 < boost < 1 相关性打分将会降低
  • boost < 0 贡献负分

比如,让包含了某项内容的结果不是不出现,而是靠后出现

POST /blogs/_bulk
{"index":{"_id":1}}
{"title":"Apple iPad","content":"Apple iPad,Apple iPad"}
{"index":{"_id":2}}
{"title":"Apple iPad,Apple iPad","content":"Apple iPad"}

GET /blogs/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": {					# 指定title字段中 查询boost的值为1
              "query": "apple,ipad",
              "boost": 1
            }
          }
        },
        {
          "match": {
            "content": {				# 指定content字段中 查询boost的值为4
              "query": "apple,ipad",
              "boost": 4
            }
          }
        }
      ]
    }
  }
}



案例:要求苹果公司的产品信息优先展示

# 添加数据
POST /news/_bulk
{"index":{"_id":1}}
{"content":"Apple Mac"}
{"index":{"_id":2}}
{"content":"Apple iPad"}
{"index":{"_id":3}}
{"content":"Apple employee like Apple Pie and Apple Juice"}

# 正常情况下 水果Apple这个数据的相关性更高,
GET /news/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "content": "Apple"
          }
        }
      ]
    }
  }
}



方式一:利用must not排除不是苹果公司产品的文档

GET /news/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "Apple"
          }
        }
      ],
      "must_not": [				# 使用 must_not 排除content中存在Pie的文档
        {
          "match": {
            "content": "Pie"
          }
        }
      ]
    }
  }
}



方式二: 利用negative_boost降低相关性

对查询结果不满意,但不能使用must_not排除掉其他文档,就可以使用negative_boost降低相关性

  • negative_boost只对negative部分的查询生效
  • 取值范围是[0,1],计算评分时,boost部分评分不更改,但是negative部分的query会 乘以 negative_boost设定的值
GET /news/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "content": "Apple"
        }
      },
      "negative": {
        "match": {
          "content": "Pie"
        }
      },
      "negative_boost": 0.2
    }
  }
}



多字段查询 相关性

我们现在学会了使用boosting query查询来降低不想查询文档的相关性,但是这还不够我们平常工作使用,在工作中很多情况下都是多字段的查询

三种场景:

  • 最佳字段 Best Fields

    多字段之间相关竞争又相互关联。比如博客的title 和 body这样的字段。最终相关性评分来自最匹配字段

  • 多数字段 Most Fields

    处理英文内容时一种常见的手段。在主字段抽取词干,加入同义词,已匹配更多的文档。相同的文本加入子字段,以提供更准确的匹配。其他字段作为匹配文档提高相关度的信号,匹配字段越多越好。最终相关性评分来自所有匹配字段之和

  • 混合字段 Cross Fields

    一次查询需要在多个字段中确定信息,单个字段只能作为整体的一部分。例如人名,地址,图书信息,希望在任何这些列出的字段中找到尽可能多的词



dis_max query最佳字段查询

将所有 与任意一个查询匹配的文档 都作为结果返回,各文档采用字段上最匹配的评分作为该文档最终相关性评分。 也就是取最大值max(a,b)

如果想要其他字段得分也参与,可以通过tie_breaker参数调整,文档最终得分_score = 最佳匹配字段得分 + 其他匹配字段得分 × tie_breaker值

准备案例数据

# 第一个文档是棕色的兔子brown rabbits       第二个文档是棕色的狐狸brown fox
DELETE /blogs
PUT /blogs/_doc/1
{
    "title": "Quick brown rabbits",
    "body":  "Brown rabbits are commonly seen."
}

PUT /blogs/_doc/2
{
    "title": "Keeping pets healthy",
    "body":  "My quick brown fox eats rabbits on a regular basis."
}

# 此时我如何要查询棕色的狐狸信息,但是显示的文档却是第一个文档相关度更高
GET /blogs/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": "brown fox" } },
        { "match": { "body": "brown fox" } }
      ]
    }
  }
}

在这里插入图片描述



bool should的算法过程:

  • 查询should语句中的两个查询
  • 加和两个查询的评分
  • 乘以匹配语句的总数
  • 除以所有语句的总数



上述例子中,title和body属于竞争关系,不应该将分数简单叠加,而是应该找到单个最佳匹配的字段的评分。

使用最佳字段查询dis max query

# 使用 dis_max 最佳匹配,文档的最终得分就不再是相加,而是直接取最高匹配项的得分
GET /blogs/_search
{
  "explain": true, 
  "query": {
    "dis_max": {
      "queries": [
        { "match": { "title": "brown fox" } },
        { "match": { "body": "brown fox" } }
      ]
    }
  }
}

在这里插入图片描述

在这里插入图片描述



可以通过tie_breaker参数调整

tie_breaker参数的取值范围为[0,1],如果为0代表使用最佳匹配字段,1代表所有字段匹配得分同等重要

文档最终得分_score = 最佳匹配字段得分 + 其他匹配字段得分 × tie_breaker值

# 使用 dis_max 最佳匹配,文档的最终得分就不再是相加,而是直接取最高匹配项的得分
# 如果使用 tie_breaker 参数,其他字段查询匹配的得分会乘以tie_breaker之后 再进行相加
GET /blogs/_search
{
  "explain": true, 
  "query": {
    "dis_max": {
      "queries": [
        { "match": { "title": "brown fox" } },
        { "match": { "body": "brown fox" } }
      ],
      "tie_breaker": 0.2
    }
  }
}



在这里插入图片描述



multi_match query

我们使用multi_match多字段匹配时,可以通过type参数来指定到底是使用最佳匹配字段 还是使用 多数字段

  • typebest_fields 使用最佳匹配字段方式。同时,它也可以添加参数tie_breaker
  • typemost_fields 表示使用所有字段匹配得分之和。等价于bool should查询方式
  • typecross_fields 表示跨字段搜索,一次搜索的内容在多个字段中显示



best_fields最佳匹配字段

type为best_fields表示最佳匹配字段,文档相关度得分_score = max(其他匹配字段得分,最佳匹配字段得分)

可以添加tie_breaker参数,取值范围是[0,1],文档相关度得分_score = 最佳匹配字段得分 + 其他匹配字段得分 × tie_breaker

type默认值就为best_fields, 可以不用指定; 也就是说multi_match query查询默认情况下等价于dis_max query

# 还是上方的案例,查询棕色狐狸
# 此时使用的是 multi_match 查询,并且type指定为best_fields,同时还使用tie_breaker参数
POST /blogs/_search
{
  "query": {
    "multi_match": {
      "type": "best_fields",			# type指定为best_fields
      "query": "Brown fox",
      "fields": ["title","body"],
      "tie_breaker": 0.2				# 使用tie_breaker参数
    }
  }
}



第二个案例,准备数据

# 创建索引时指定默认分词器
PUT /employee
{
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

POST /employee/_bulk
{"index":{"_id":1}}
{"empId":"1","name":"员工001","age":20,"sex":"男","mobile":"19000001111","salary":23343,"deptName":"技术部","address":"湖北省武汉市洪山区光谷大厦","content":"i like to write best elasticsearch article"}
{"index":{"_id":2}}
{"empId":"2","name":"员工002","age":25,"sex":"男","mobile":"19000002222","salary":15963,"deptName":"销售部","address":"湖北省武汉市江汉路","content":"i think java is the best programming language"}
{"index":{"_id":3}}
{"empId":"3","name":"员工003","age":30,"sex":"男","mobile":"19000003333","salary":20000,"deptName":"技术部","address":"湖北省武汉市经济开发区","content":"i am only an elasticsearch beginner"}
{"index":{"_id":4}}
{"empId":"4","name":"员工004","age":20,"sex":"女","mobile":"19000004444","salary":15600,"deptName":"销售部","address":"湖北省武汉市沌口开发区","content":"elasticsearch and hadoop are all very good solution, i am a beginner"}
{"index":{"_id":5}}
{"empId":"5","name":"员工005","age":20,"sex":"男","mobile":"19000005555","salary":19665,"deptName":"测试部","address":"湖北省武汉市东湖隧道","content":"spark is best big data solution based on scala, an programming language similar to java"}
{"index":{"_id":6}}
{"empId":"6","name":"员工006","age":30,"sex":"女","mobile":"19000006666","salary":30000,"deptName":"技术部","address":"湖北省武汉市江汉路","content":"i like java developer"}
{"index":{"_id":7}}
{"empId":"7","name":"员工007","age":60,"sex":"女","mobile":"19000007777","salary":52130,"deptName":"测试部","address":"湖北省黄冈市边城区","content":"i like elasticsearch developer"}
{"index":{"_id":8}}
{"empId":"8","name":"员工008","age":19,"sex":"女","mobile":"19000008888","salary":60000,"deptName":"技术部","address":"湖北省武汉市江汉大学","content":"i like spark language"}
{"index":{"_id":9}}
{"empId":"9","name":"员工009","age":40,"sex":"男","mobile":"19000009999","salary":23000,"deptName":"销售部","address":"河南省郑州市郑州大学","content":"i like java developer"}
{"index":{"_id":10}}
{"empId":"10","name":"张湖北","age":35,"sex":"男","mobile":"19000001010","salary":18000,"deptName":"测试部","address":"湖北省武汉市东湖高新","content":"i like java developer, i also like elasticsearch"}
{"index":{"_id":11}}
{"empId":"11","name":"王河南","age":61,"sex":"男","mobile":"19000001011","salary":10000,"deptName":"销售部","address":"河南省开封市河南大学","content":"i am not like java"}
{"index":{"_id":12}}
{"empId":"12","name":"张大学","age":26,"sex":"女","mobile":"19000001012","salary":11321,"deptName":"测试部","address":"河南省开封市河南大学","content":"i am java developer, java is good"}
{"index":{"_id":13}}
{"empId":"13","name":"李江汉","age":36,"sex":"男","mobile":"19000001013","salary":11215,"deptName":"销售部","address":"河南省郑州市二七区","content":"i like java and java is very best, i like it, do you like java"}
{"index":{"_id":14}}
{"empId":"14","name":"王技术","age":45,"sex":"女","mobile":"19000001014","salary":16222,"deptName":"测试部","address":"河南省郑州市金水区","content":"i like c++"}
{"index":{"_id":15}}
{"empId":"15","name":"张测试","age":18,"sex":"男","mobile":"19000001015","salary":20000,"deptName":"技术部","address":"河南省郑州市高新开发区","content":"i think spark is good"}
# multi_match全文检索 多字段匹配,type默认值为best_fields
# 默认使用的就是最佳匹配字段
GET /employee/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "elasticsearch beginner 湖北省 开封市",
      "fields": ["address", "content"],
      "type": "best_fields"
    }
  }
}

# 使用 tie_breaker 参数
GET /employee/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "elasticsearch beginner 湖北省 开封市",
      "fields": ["address", "content"],
      "type": "best_fields",
      "tie_breaker": 0.4				# 使用tie_breaker参数
    }
  }
}

在这里插入图片描述

在这里插入图片描述



most_fields 多数字段搜索

type为most_fields 表示最佳匹配字段,文档相关度得分_score = sum(所有匹配字段得分),等价于bool should查询方式

# multi_match全文检索 多字段匹配,type指定为most_fields
GET /employee/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "elasticsearch beginner 湖北省 开封市",
      "fields": ["address", "content"],
      "type": "most_fields"
    }
  }
}

在这里插入图片描述



案例数据准备

DELETE /titles
PUT /titles
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "english",		# 指定分词器
        "fields": {
          "std": {		# 指定一个子类型位srd
            "type": "text",
            "analyzer": "standard"	# 指定分词器
          }
        }
      }
    }
  }
}

POST titles/_bulk
{ "index": { "_id": 1 }}
{ "title": "My dog barks" }
{ "index": { "_id": 2 }}
{ "title": "I see a lot of barking dogs on the road " }

# 结果与预期不匹配,此时我想查询id为2的文档,但是id为1文档的相关度更高
GET /titles/_search
{
  "query": {
    "match": {
      "title": "barking dogs"
    }
  }
}

在这里插入图片描述



用广度匹配字段title包括尽可能多的文档——以提升召回率——同时又使用字段title.std 作为信号将相关度更高的文档置于结果顶部。

GET /titles/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "barking dogs",
      "fields": ["title","title.std"],
      "type": "most_fields"
    }
  }
}

在这里插入图片描述



每个字段对于最终评分的贡献可以通过自定义值boost 来控制。比如,使title 字段更为重要,这样同时也降低了其他信号字段的作用:

#增加title字段的权重
GET /titles/_search
{
  "query": {
    "multi_match": {
      "query": "barking dogs",
      "type": "most_fields",
      "fields": [
        "title^10",
        "title.std"
      ]
    }
  }
}

在这里插入图片描述



cross_fields跨字段搜索

搜索内容在多个字段中都显示

案例数据

DELETE /address
PUT /address
{
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "长沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "广州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵阳"}



我想查询湖南常德的数据,但是搜索的结果会把id=1 和 id=4的文档都显示出来,因为湖南这个term词项会匹配

# 查询湖南常德的文档数据,
# 使用most_fields的方式结果不符合预期,不支持operator
GET /address/_search
{
  "query": {
    "multi_match": {
      "query": "湖南常德",
      "fields": ["province", "city"]
    }
  }
}



此时就可以使用type指定为cross_fields,这样支持operator了

# 与copy_to相比,其中一个优势就是它可以在搜索时为单个字段提升权重。
GET /address/_search
{
  "query": {
    "multi_match": {
      "query": "湖南常德",
      "fields": ["province", "city"],
      "type": "cross_fields",
      "operator": "and"
    }
  }
}



可以用copy...to 解决,但是需要额外的存储空间

DELETE /address
# copy_to参数允许将多个字段的值复制到组字段中,然后可以将其作为单个字段进行查询
PUT /address
{
  "mappings" : {
      "properties" : {
        "province" : {
          "type" : "keyword",
          "copy_to": "full_address"			# 使用copy_to
        },
        "city" : {
          "type" : "text",
          "copy_to": "full_address"			# 使用copy_to
        }
      }
    },
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "长沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "广州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵阳"}

# 此时就可以通过 full_address 字段来进行搜索匹配
GET /address/_search
{
  "query": {
    "match": {
      "full_address": {
        "query": "湖南常德",
        "operator": "and"
      }
    }
  }
}

在这里插入图片描述

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

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

相关文章

Ubuntu 通过 docker 安装 Nginx 镜像 + 创建并运行 nginx01 容器

一、安装 nginx:精简版镜像 1. 查找有什么类型的 nginx 镜像 yammiemy-pc >/home/yammie $ docker search nginx 2. 下载精简版 nginx 镜像 yammiemy-pc >/opt $ docker pull nginx:alpine alpine: Pulling from library/nginx 46b060cc2620: Already exists 21af147…

【深度学习|目标跟踪】快速入门卡尔曼滤波!

卡尔曼滤波详解 申明一、什么是卡尔曼滤波1.1 卡尔曼滤波的使用场景1.2 卡尔曼滤波的定义 二、卡尔曼滤波公式详解&#xff08;无推导&#xff09;三、卡尔曼滤波的简单应用 申明 本博客参考了b站up主“华南小虎队”的卡尔曼滤波教学视频以及Lauszus Kristian Sloth Lauszus的卡…

联想Thinkpad驱动安装下载(官网的驱动下载)

联想Thinkpad驱动安装官网下载地址&#xff1a; 联想驱动管理_ThinkPad服务网站-联想服务 联想驱动管理 帮助您更快速准确的定位驱动 自动下载安装,安装驱动不求人 软件版本&#xff1a;V2.9.0719.1104 | 大小&#xff1a;5.7M最后更新&#xff1a;2021-07-21支持系统&#…

41.【C语言之外】聊聊Cheat Engine官方教程步骤6的思考

0.看前须知 有一定指针概念的基础 推荐阅读前几篇博文&#xff1a; 19.【C语言】指针&#xff08;重难点&#xff09;&#xff08;A&#xff09; 37.【C语言】指针&#xff08;重难点&#xff09;&#xff08;B&#xff09; 38.【C语言】指针&#xff08;重难点&#xff09…

oracle的exp.exe、imp.exe在哪下载?

需要oracle账号 地址&#xff1a; Instant Client for Microsoft Windows (x64) 64-bit 下载这个工具包

开发一个能打造虚拟带货直播间的工具!

在当今数字化时代&#xff0c;直播带货已成为电商领域的一股强劲力量&#xff0c;其直观、互动性强的特点极大地提升了消费者的购物体验。 然而&#xff0c;随着技术的不断进步&#xff0c;传统直播带货模式正逐步向更加智能化、虚拟化的方向演进&#xff0c;本文将深入探讨如…

智慧景区系统开发功能定制

智慧景区系统开发功能定制是一项综合性服务&#xff0c;它涉及到利用云计算、物联网、AI监控等先进技术&#xff0c;通过互联网和移动互联网&#xff0c;实现景区智慧化管理和服务提升。 以下是智慧景区系统开发中应考虑的关键功能点&#xff1a; 游客服务平台&#xff1a;包…

23款奔驰E350eL升级原厂香氛负离子系统,保持一股高级的香味

相信大家都知道&#xff0c;奔驰自从研发出香氛负离子系统后&#xff0c;一直都受广大奔驰车主的追捧&#xff0c;香氛负离子不仅可以散发出清香淡雅的香气外&#xff0c;还可以对车内的空气进行过滤&#xff0c;使车内的有害气味通过负离子进行过滤&#xff0c;达到车内保持清…

“AI能不能代替某某职业”,到底谁在破防?

前几天&#xff0c;公司在午间分享时谈到一个有趣的辩题&#xff1a;“AI能不能代替产品经理”&#xff0c;不仅双方辩手打了个你来我往&#xff0c;就连下面的吃瓜群众也进入红温状态。 “AI能不能代替xx”已经成为一个普遍的话题&#xff0c;在某乎上随手一刷就是不同的职业…

Linux 利用 ftrace 分析内核调用

目录 一、概述二、ftrace 的使用1、常用信息2、指定 ftrace 跟踪器3、设置要跟踪的函数4、ftrace 的开关5、function 跟踪程序6、function_graph 跟踪程序7、函数过滤器8、跟踪事件 三、trace-cmd 的使用1、常见命令2、常用选项2.1 列出可用的追踪器2.2 跟踪特定进程的函数调用…

如何用剪映自动批量生成左右分屏的视频?

做tiktok中视频计划的朋友&#xff0c;应该都知道一种批量做号的模式&#xff0c;就是找一些热门视频作为左边主机视频&#xff0c;右边则放上一些减压类视频以保存画面的原创度&#xff0c;像下面这种。 这种视频是如何批量用剪映生成的呢&#xff1f; 一、准备好素材 下载好…

数据结构——栈的讲解(超详细)

前言&#xff1a; 小编已经在前面讲完了链表和顺序表的内容&#xff0c;下面我们继续乘胜追击&#xff0c;开始另一个数据结构&#xff1a;栈的详解&#xff0c;下面跟上小编的脚步&#xff0c;开启今天的学习之路&#xff01; 目录 1.栈的概念和结构 1.1.栈的概念 1.2.栈的结构…

redis面试(十五)公平锁队列重排

队列重拍 先说一下当前的加锁状态 anyLock由客户端A持有队列中是客户端B、客户端C并且客户端B现在是排在头部 那么队列重拍就是队列中某个客户端长时间没有重新申请加锁&#xff0c;没有刷新分数&#xff0c;就会被队列中挤掉。 假设这个长时间没有加锁的客户端是B。 总结 …

C++ CMake FFmpeg配置

SDK下载 github 环境变量配置 cmake_modules/FindFFmpeg.cmake # This module defines the following variables: # # FFmpeg_FOUND - All required components and the core library were found # FFmpeg_INCLUDE_DIRS - Combined list of all components includ…

Dijkstra单源最短路径算法学习有感

认识Dijkstra 艾兹格维布迪克斯特拉&#xff08;Edsger Wybe Dijkstra&#xff0c;/ˈdaɪkstrə/ DYKE-strə&#xff1b;荷兰语&#xff1a;[ˈɛtsxər ˈʋibə ˈdɛikstra] 1930年5月11日-2002年8月6日&#xff09;是一位荷兰计算机科学家、程序员、软件工程师、系统科学…

(回溯) LeetCode 46. 全排列

原题链接 一. 题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#xff1a;…

零基础学习Redis(1) -- Redis简介

Redis是一个在内存中存储数据的一个中间组件&#xff0c;可用作数据库或数据缓存&#xff0c;通常在分布式系统中使用 &#xff08;不了解分布式&#xff1f; 点击传送&#xff09; 1. Redis特性 在内存中存储数据&#xff0c;通过键值对的方法存储key为string&#xff0c;v…

[GYCTF2020]FlaskApp1

打开题目 简单的一个base64加解密小程序 查看提示&#xff0c;好像并没有什么用&#xff0c;题目是flask&#xff0c;可能是ssti模板注入 加密窗口{{77}},解密窗口e3s3Kzd9fQ ({{77}} 加密窗口没看到注入&#xff0c;解密窗口存在注入&#xff0c;是模板注入 读取文件内容&am…

JimV私有云平台部署及应用

1. JimV概述 1.1 介绍 JimV 是一个&#xff0c;结构精简&#xff0c;易于部署、维护、使用的&#xff0c;企业私有云管理平台。JimV 基于 KVM 开发而来&#xff0c;通过 JimV 管理平台&#xff0c;可以批量创建、管理虚拟机。 JimV 更为轻量级&#xff0c;使用户轻易拥有维护…

【Day05】0基础微信小程序入门-学习笔记

文章目录 基础加强学习目标使用npm包1.准备项目2. 小程序对于npm的支持和限制3. Vant Weapp小程序UI组件库4. 使用Vant组件5. 定制全局主题样式6. API Promise化 全局数据共享1. 简介2. MobX2.1 安装MobX相关包并构建npm2.2 创建MobX的Store实例2.3 将Store成员绑定到页面中2.4…