Treesystem - 术哥
type: channel
link: https://treesystem.cn/author/1/
description: 术哥
items: 🔇Windows中实现锁屏自动静音
items: 常用工具箱
items: 一键修复与安装脚本(各种linux系统修复与服务器环境安装脚本)
items: MySQL 批量转换表字符集以及排序方式
items: [译] NAT 穿透是如何工作的：技术原理及企业级实践（Tailscale, 2020）
items: NVM小笔记
items: 重装系统大作战
items: 为Elasticsearch添加Basic鉴权
items: 【小技巧】为Web再加上一把锁
items: 【转载】一起来学ES —— 浅谈Nested结构

🔇Windows中实现锁屏自动静音
type: item
date: 2025-03-27T22:11:00+08:00
description: 需求防止我在梦中惊醒，一怒之下整了这个脚本实现实现锁屏静音🔇，解锁恢复锁屏前就是静音状态，则解锁保持静音🔇接住AudioDeviceCmdlets模块，运行几乎无压力代码把下面代码用自带记事本保存，文件名（包括扩展名）改成 SetupMuteOnLock.ps1 并使用管理员权限运行。# 需要以管理员权限运行 if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Host "请以管理员权限运行此脚本！" -ForegroundColor Red Start-Sleep -Seconds 3 exit } Write-Host "正在设置锁屏自动静音功能..." -ForegroundColor Green # 创建脚本目录 $scriptDir = "$env:USERPROFILE\LockScreenMuteScripts" if (-not (Test-Path -Path $scriptDir)) { New-Item -Path $scriptDir -ItemType Directory | Out-Null } # 检查AudioDeviceCmdlets模块是否安装 $moduleInstalled = Get-Module -ListAvailable -Name AudioDeviceCmdlets if (-not $moduleInstalled) { Write-Host "安装AudioDeviceCmdlets模块..." -ForegroundColor Yellow Install-Module -Name AudioDeviceCmdlets -Force -Scope CurrentUser Write-Host "AudioDeviceCmdlets模块安装成功！" -ForegroundColor Green } # 创建静音脚本 (使用VBS包装以隐藏PowerShell窗口) $mutePath = "$scriptDir\Mute.ps1" @" # 保存当前音量状态 Import-Module AudioDeviceCmdlets # 获取当前状态 `$isMuted = Get-AudioDevice -PlaybackMute # 保存状态到文件 "`$isMuted" | Out-File -FilePath "$env:USERPROFILE\volume_state.txt" -Force # 设置静音 Set-AudioDevice -PlaybackMute `$true "@ | Out-File -FilePath $mutePath -Encoding utf8 # 创建取消静音脚本 (使用VBS包装以隐藏PowerShell窗口) $unmutePath = "$scriptDir\Unmute.ps1" @" # 恢复之前的音量状态 Import-Module AudioDeviceCmdlets # 读取保存的状态 if (Test-Path -Path "$env:USERPROFILE\volume_state.txt") { `$savedState = Get-Content -Path "$env:USERPROFILE\volume_state.txt" `$wasMuted = [System.Convert]::ToBoolean(`$savedState) # 如果之前没有静音，则恢复 if (-not `$wasMuted) { Set-AudioDevice -PlaybackMute `$false } } "@ | Out-File -FilePath $unmutePath -Encoding utf8 # 创建VBS包装脚本（完全隐藏窗口） $muteVbsPath = "$scriptDir\Mute.vbs" @" Set objShell = CreateObject("Wscript.Shell") command = "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -NonInteractive -File ""$mutePath""" objShell.Run command, 0, False "@ | Out-File -FilePath $mut…

常用工具箱
type: item
date: 2024-12-26T11:49:00+08:00
description: Docker一键安装并解决国内镜像加速问题bash <(curl -sSL https://linuxmirrors.cn/docker.sh)GitHubGitHub官方中国大陆加速服务将任意 github.com地址改成 github.siteIP类ipw.cn 查看IPV4和IPV6地址查看网络出口查询IP信息查看IP干净度

一键修复与安装脚本(各种linux系统修复与服务器环境安装脚本)
type: item
date: 2024-12-20T00:04:00+08:00
description: 转载：https://github.com/spiritLHLS/one-click-installation-script前言所有脚本如需在国内服务器使用，请在链接前加上 https://cdn.spiritlhl.net/确保命令可以下载本仓库的shell脚本执行目录一键修复脚本一键尝试修复apt源一键尝试修复系统时间一键尝试修复sudo警告一键修改系统自带的journal日志记录大小释放系统盘空间一键尝试修复网络一键解除进程数限制一键环境安装脚本一键安装golang环境一键安装jupyter环境一键安装R语言环境一键安装rust环境一键安装C++环境一键安装vnstat环境一键升级低版本debian为debian11一键升级低版本ubuntu为ubuntu22一键安装zipline平台一键安装filebrowser平台一键删除平台监控部分手动命令一键开启root登陆并替换密码一键屏蔽邮件端口避免被恶意程序使用设置语言包ubuntu更新源被锁debian缺失公钥ubuntu或debian缺失公钥centos换源安装gitea卸载aapanel查询是什么东西占用硬盘大于100M卸载dns缓存机制避免配置覆写安装docker和docker-compose通过docker安装code-server友链一键测试服务器的融合怪脚本一键批量开NAT服务器LXC一键安装PVE朋友fscarmen的常用一键工具仓库一键修复脚本运行所有一键修复脚本前注意看说明，以及保证服务器无重要数据，运行后造成的一切后果作者不负任何责任，自行评判风险！一键尝试修复apt源支持系统：Ubuntu 12+，Debian 6+修复apt下载包进程意外退出导致的源锁死修复apt源broken损坏修复apt源多进程占用锁死修复apt源公钥缺失修复替换系统可用的apt源列表，国内用阿里源，国外用官方源修复本机的Ubuntu系统是EOL非长期维护的版本(奇数或陈旧的偶数版本)，将替换为Ubuntu官方的old-releases仓库以支持apt的使用修复只保证 apt update不会报错，其他命令报错未修复如若修复后install还有问题，重启服务器解决问题curl -L https://raw.githubusercontent.com/spiritLHLS/one-click-installation-script/main/repair_scripts/package.sh -o package.sh && chmod +x package.sh && bash package.sh一键尝试修复系统时间支持系统：Ubuntu 18+，Debian 8+，centos 7+，Fedora，Almalinux 8.5+由于系统时间不准确都是未进行时区时间同步造成的，使用chronyd进行时区时间同步后应当解决了问题curl -L https://raw.githubusercontent.com/spiritLHLS/one-click-installation-script/main/repair_scripts/modify_time.sh -o modify_time.sh && chmod +x modify_time.sh && bash modify_time.sh一键尝试修复sudo警告一键尝试修复 sudo: unable to resolve host xxx: Name or service not known警告(爆错)不要在生产环境上使用该脚本，否则容易造成网络hosts配置错误，配置的host名字不在外网IP上反而在内网IP(127.0.0.1)上curl -L https://raw.githubusercontent.com/spiritLHLS/one-click-installation-script/main/repair_scripts/check_sudo.sh -o check_sudo.sh && chmod +x check_sudo.sh && bash check_sudo.sh一键修改系统自带的journal日志记录大小释放系统盘空间支持系统：Ubuntu 18+，Debian 8+，centos 7+，Fedora，Almalinux 8.5+1.自定义修改大小，单位为MB，一般500或者1000即可，有的系统日志默认给了5000甚至更多，不是做站啥的没必要请注意，修改journal目录大小会影响系统日志的记录，因此，在修改journal目录大小之前如果需要之前的日志，建议先备份系统日志到本地2.自定义修改设置系统日志保留日期时长，超过日期时长的日志将被清除3.默认修改日志只记录warning等级(无法自定义)4…

MySQL 批量转换表字符集以及排序方式
type: item
date: 2024-01-18T11:14:00+08:00
description: [scode type="red" size=""]⚠ 数据安全须知！！！数据无价！！！在做转换前需要先备份再操作，操作过程中出现异常，作者不负任何责任！[/scode]1·选择您的数据库：USE your_database_name;2.获取所有表的名称并生成ALTER TABLE语句。您可以通过执行以下命令来完成这个步骤：SELECT CONCAT('ALTER TABLE `', table_name, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;') AS _sql FROM information_schema.TABLES WHERE table_schema = "your_database_name" AND table_type = "BASE TABLE";这个查询会为您的数据库中的每个表生成一个 ALTER TABLE语句。注意将 your_database_name替换成您实际的数据库名称。将上述查询的结果复制到一个SQL脚本文件中或者直接在MySQL命令行中运行它们。3.验证您的服务是否正常，返回结果是否在预期内。

[译] NAT 穿透是如何工作的：技术原理及企业级实践（Tailscale, 2020）
type: item
date: 2024-01-17T22:55:00+08:00
description: 译者序本文翻译自 2020 年的一篇英文博客： How NAT traversal works。设想这样一个问题：在北京和上海各有一台==局域网的机器==（例如一台是家里的台式机，一 台是连接到星巴克 WiFi 的笔记本），二者都是私网 IP 地址，但可以访问公网， ==如何让这两台机器通信呢？==既然二者都能访问公网，那最简单的方式当然是在公网上架设一个中继服务器： 两台机器分别连接到中继服务，后者完成双向转发。这种方式显然有很大的性能开销，而 且中继服务器很容易成为瓶颈。有没有办法不用中继，让==两台机器直接通信==呢？如果有一定的网络和协议基础，就会明白这事儿是可能的。Tailscale 的这篇==史诗级长文==由浅入深地展示了这种“可能”，如果完全实现本文所 介绍的技术，你将得到一个企业级的 NAT/防火墙穿透工具。 此外，如作者所说，==去中心化软件==领域中的许多有趣想法，简化之后其实都变成了 ==跨过公网（互联网）实现端到端直连== 这一问题，因此本文的意义并不仅限于 NAT 穿透本身。由于译者水平有限，本文不免存在遗漏或错误之处。如有疑问，请查阅原文。以下是译文。网页版目录在右侧小程序目录在底层在前一篇文章 How Tailscale Works 中， 我们已经用较长篇幅介绍了 Tailscale 是如何工作的。但其中并没有详细描述我们是 ==如何穿透 NAT 设备，从而实现终端设备直连的== —— 不管这些终端之间 有什么设备（防火墙、NAT 等），以及有多少设备。本文试图补足这一内容。1 引言1.1 背景：IPv4 地址短缺，引入 NAT全球 IPv4 地址早已不够用，因此人们发明了 NAT（网络地址转换）来缓解这个问题。简单来说，大部分机器都使用==私有 IP 地址==，如果它们需要访问公网服务，那么，出向流量：需要经过一台 NAT 设备，它会对流量进行 SNAT，将私有 srcIP+Port 转 换成 NAT 设备的公网 IP+Port（这样应答包才能回来），然后再将包发出去；应答流量（入向）：到达 NAT 设备后进行相反的转换，然后再转发给客户端。整个过程对双方透明。更多关于 NAT 的内容，可参考 (译) NAT - 网络地址转换（2016）。 译注。以上是本文所讨论问题的==基本背景==。1.2 需求：两台经过 NAT 的机器建立点对点连接在以上所描述的 NAT 背景下，我们从最简单的问题开始：如何在两台经过 NAT 的机器之间建立 ==点对点连接==（直连）。如下图所示：直接用机器的 IP 互连显然是不行的，因为它们都是私有 IP（例如 192.168.1.x）。 在 Tailscale 中，我们会建立一个 ==WireGuard® 隧道== 来解决这个问题 —— 但这并不是太重要，因为我们将==过去几代人努力==都整合到了一个工具集， ==这些技术广泛适用于各种场景==。例如，==WebRTC== 使用这些技术在浏览器之间完成 peer-to-peer 语音、视频和数据传输，==VoIP 电话和一些视频游戏==也使用类似机制，虽然不是所有情况下都很成功。接下来，本文将==在一般意义上讨论这些技术==，并在合适的地方拿 Tailscale 和其他一些东西作为例子。1.3 方案：NAT 穿透1.3.1 两个必备前提：UDP + 能直接控制 socket如果想==设计自己的协议来实现 NAT 穿透==，那必须满足以下两个条件：==协议应该基于 UDP==。理论上用 TCP 也能实现，但它会给本已相当复杂的问题再增加一层复杂性， 甚至还需要定制化内核 —— 取决于你想实现到什么程度。本文接下来都将关注在 UDP 上。如果考虑 TCP 是想在 NAT 穿透时获得==面向流的连接==（ stream-oriented connection），可以考虑用 ==QUIC== 来替代，它构 建在 UDP 之上，因此我们能将关注点放在 UDP NAT 穿透，而仍然能获得一个 很好的流协议（stream protocol）。对收发包的 ==socket 有直接控制权==。例如，从经验上来说，无法基于某个现有的网络库实现 NAT 穿透，因为我们 ==必须在使用的“主要”协议之外，发送和接收额外的数据包==。某些协议（例如 WebRTC）将 NAT 穿透与其他部分紧密集成。但如果你在构建自己的协议， ==建议将 NAT 穿透作为一个独立实体，与主协议并行运行==，二者仅 仅是共享 socket 的关系，如下图所示，这将带来很大帮助：1.3.2 保底方式：中继在某些场景中，直接访问 socket 这一条件可能很难满足。退而求其次的一个方式是设置一个 local proxy（本地代理），主协议与这个 proxy 通信 ，后…

NVM小笔记
type: item
date: 2024-01-12T09:51:00+08:00
description: 安装Github安装链接curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bashGitee安装链接（含设定淘宝镜像源，适用中国大陆）curl -o- https://gitee.com/RubyMetric/nvm-cn/raw/main/install.sh | bash更新nvm安装时可能使用旧版的nvm程序，可在安装后执行一次更新命令。nvm update上述命令执行时，请确保有权限。例外操作可能会遭遇受限权限写入或者需要重载环境等情况，通常执行以下命令可恢复正常。# 更新权限 chmod +x ~/.nvm/nvm.sh # 重新加载环境变量 source ~/.bashrcnvm指令查看当前机器安装版本nvm ls查看可以云端版本nvm ls-remote安装指定版本Node.jsnvm install [<version>]卸载指定Node.js版本nvm uninstall [<version>]使用指定Node.js版本nvm use [<version>]当前使用Node.js版本nvm current在对应项目中切换不同Node.js版本在项目中创建项目所需要的版本声明touch .nvmrc echo "v18.19.0" >> .nvmrc在指定目录下使用nvm use即可切换到对应版本也可以使用其他方式在使用npm时自动辨识项目的版本文件进行切换操作。NVM命令输出选项原文Node Version Manager (v0.39.5) Note: <version> refers to any version-like string nvm understands. This includes: - full or partial version numbers, starting with an optional "v" (0.10, v0.1.2, v1) - default (built-in) aliases: node, stable, unstable, iojs, system - custom aliases you define with `nvm alias foo` Any options that produce colorized output should respect the `--no-colors` option. Usage: nvm --help Show this message --no-colors Suppress colored output nvm --version Print out the installed version of nvm nvm install [<version>] Download and install a <version>. Uses .nvmrc if available and version is omitted. The following optional arguments, if provided, must appear directly after `nvm install`: -s Skip binary download, install from source only. -b Skip source download, install from binary only. --reinstall-packages-from=<version> When installing, reinstall packages installed in <node|iojs|node version number> --lts When installing, only select from LTS (long-term support) versions --lts=<LTS name> When installing, only select from versions for a specific LTS line --skip-default-packages When installing, skip the default-packages file if it exists --latest-npm After installing, attempt to upgrade to the latest working npm on the given node version --no-progress Disable the progress bar on any downloads --al…

重装系统大作战
type: item
date: 2023-08-13T15:48:00+08:00
description: 0. 准备物料物料用途16GB以上U盘用于引导和存放重装系统介质微PE工具箱安装文件用于引导电脑进入工具箱安装系统系统镜像依照您的电脑当前的系统版本准备，本文以Win10为例1. 部署拯救U盘非常强烈大家使用一个U盘提前部署PE系统，且部署此系统不会影响正常U盘的使用，以备系统崩溃或者紧急修复使用。1.1 获取微PE工具箱本文推荐微PE工具箱，推荐的点：简单，边界，无广告。下载地址：https://www.wepe.cn/download.html如何选择版本：一般选择最新的即可，如果最新的PE工具箱无法运行，则直接安装最老版本。如果你了解电脑的启动方式为UEFI，则选择最新，反之最老1.2 安装微PE工具箱准备一个大于16GB的U盘，请备份U盘中的数据，因为在接下来的过程中会格式化U盘。打开下载的文件，选择右下角的其他安装方式：安装到U盘切换到安装到U盘界面，默认选项一般无需改动，但建议勾选下面两个选项，最后选择安装到U盘即可[x] 包含DOS工具[x] 同时复制安装包⚠ 在安装前再次提示：安装会格式化U盘：指U盘的数据会被全部清空，请提前备份数据！暂时关闭安防软件：因为需要对U盘分区以及加载引导，部分安防软件会阻止程序写入。最后等待软件提示安装成功即可。1.3 认识新U盘在安装成功后，电脑上会识别出2个分区：分区名可使用？备注未命名（或者根据安装时填写的U盘卷名，通常也是空间最大的一个）可以日常使用U盘文件存放分区EFI不可以用于引导急救系统，不要修改内部文件在日常使用过程中建议为日常使用分区做独立标识名，以便自己或借给他人使用能够了解。1.4 复制安装镜像请在U盘分区的根目录下创建一个文件夹system_images，将您的安装镜像复制到这个文件夹中。安装镜像类型可以为：*.ios*.wim*.gho建议放您常用的系统以便安装，建议使用原版镜像或可靠的安全来源镜像。2. 启动重装之路2.1 了解BIOS引导本文不会解释引导逻辑，但您需要知道目前有两种引导模式，且两者一般对应不同的分区表UEFI启动 -> GPT分区表Legacy启动 -> MBR分区表在目前主流的电脑多数使用UEFI启动，部分老旧的电脑使用Legacy启动，但我们也可以通过引导菜单来简要查看。引导菜单快捷键：如果您的电脑不在上述表中或按键无响应，则需要自行百度一下，你就知道。2.2 选择启动设备如果成功进入引导菜单，将会看到下面的示例引导菜单：支持UEFI启动，一般在设备名称前会有UEFI或者EFI字样，选择含有此前缀的U盘，查看是否能够正常进入PE工具箱系统画面。此处为WindowsPE系统选择界面：默认等待进入第一选项或者直接回车。如果第一个选项在您的电脑上无法显示，则需要选择第二个选项进入。等待系统加载：最终能够展示PE系统界面，即成功一大步~如果在UEFI模式下启动失败，则需要使用Legacy启动重新加载PE系统。2.3 别着急，还需要再确认分区表在一开始介绍了电脑的两种启动模式，但这不代表你你的电脑原本就是使用现有方式进入。如果使用Legacy启动则可以不需要再确认了，因为您的电脑只有MBR分区表。打开分区工具：GPT分区表：MBR：从上方两张图也可以很直观的看出，GPT分区表是至少有3个分区起（部分GPT也有2个分区），且首个分区也有我们一开始再认识新U盘上提到的EFI分区。因此本着不修改原有分区表的原则，进行重装系统。重点提示：如果您使用UEFI启动进入PE工具箱发现分区表为MBR，则需要回到选择启动设备阶段 ，选择不含有UEFI或EFI字样的U盘设备重新启动PE工具箱。此外解释一下为什么不修改分区表，原因有很多：可能这个电脑原生不支持UEFI启动，或为虚拟UEFI不完善。小白可能改了分区表可能不会配置BIOS启动模式，导致无法启动系统。转换分区表还需要额外建立引导分区或激活分区。MBR分区不支持2TB以上的硬盘。其他原因...如果您大胆尝试，可以修改分区表尝试是否能够使用UEFI进行启动系统，但建议在有专业人员的指导下进行修改。3. 改写系统的命运3.1 改写启动！启动桌面上CGI备份还原软件：3.2 选择镜像打开软件后：软件一般会自动选择系统盘，但还需要自己再确认一下，以免格式化到其他分区。在下方选择放在system_images文件夹下的镜像。ISO文件或者WIM文件一般内部会有多个系统镜像，会自动弹出新的窗口再选择安装需要的系统版本：最后再下方确认安装分区以及系统版本无误点击执行：3.3 最终确认需要勾选以下选项：[x] 格式化[x] 修复引导[x] 完成后重启，等待还原完成：在非专业人员情况下，尽量不要动电脑以及插拔U盘。进度条有可能会多次归零，不必担心，耐心等待安装完成自动重启。4. 新系统命运到来4.0 重启又进PE工具箱？如…

为Elasticsearch添加Basic鉴权
type: item
date: 2022-05-27T18:41:00+08:00
description: 前言在很久很久以前，一位萌新程序员小明用Docker安装了Elasticsearch，之后很久很久没有在管过了，但偶然的一次对服务器检查发现ES中存在一堆的数据，小明立马意识到ES的服务被他人使用了，急忙关闭了服务并查询如何对ES进行添加鉴权。技术点Elasticsearch,Nginx（可选）实战第一种：ES启用鉴权本次ES运行版本为7.17.2，不同的版本可能会存在配置不同，可能需要查询下当前版本的手册较佳。elasticsearch.yml对配置文件添加如下配置http.cors.enabled: true http.cors.allow-origin: "*" http.cors.allow-headers: Authorization xpack.security.enabled: true xpack.security.transport.ssl.enabled: true添加配置后重启服务发现再次访问ES服务则需要提示输入账户密码，点击取消会有401的错误提示.配置密码配置完上一步，此时服务是不可访问，，因此我们还需要在终端配置密码。术哥@ubuntu:/usr/share/elasticsearch# elasticsearch-setup-passwords interactive Initiating the setup of passwords for reserved users elastic,apm_system,kibana,kibana_system,logstash_system,beats_system,remote_monitoring_user. You will be prompted to enter passwords as the process progresses. Please confirm that you would like to continue [y/N] y Enter password for [elastic]: Reenter password for [elastic]: Enter password for [apm_system]: Reenter password for [apm_system]: Enter password for [kibana_system]: Reenter password for [kibana_system]: Enter password for [logstash_system]: Reenter password for [logstash_system]: Enter password for [beats_system]: Reenter password for [beats_system]: Enter password for [remote_monitoring_user]: Reenter password for [remote_monitoring_user]: Changed password for user [apm_system] Changed password for user [kibana_system] Changed password for user [kibana] Changed password for user [logstash_system] Changed password for user [beats_system] Changed password for user [remote_monitoring_user] Changed password for user [elastic]Change完成后就重启服务，访问ES服务，输入账号elastic和你设置的密码既可。第二种：使用Nginx添加Basic鉴权此方法就比较简单了，不需要得ES内进行配置，则使用Nginx进行端口转发且添加Basic鉴权，就直接上配置文件了。如何生成鉴权文件可参考上一篇文章【小技巧】为Web再加上一把锁。配置文件注意：此配置文件只显示需要改动点，并不能直接复制粘贴使用 steam es{ server 127.0.0.1:9200 } server { auth_basic "admin area"; # 启用鉴权 auth_basic_user_file "/etc/nginx/http_auth/.{domain}.pass"; # 指定鉴权文件 location / { http_proxy es; } }成果鉴权成功[图片未上传]鉴权失败[图片未上传]额外的点Kibana鉴权由于我们为ES添加了鉴权，因此Kibana这块也需要在配置文件上添加对应配置[配置中心未…

【小技巧】为Web再加上一把锁
type: item
date: 2022-05-25T15:04:00+08:00
description: 前言有几次在学习的时候，官方提供的工具刚好是一个对Web工具没有任何加密措施，毕竟学习是无时无刻（说白了就是无时无刻的卷），虽然都是一些学习数据，将服务直接暴露在公网上总是觉得不安全，因此对Web服务额外进行Basic验证。技术点Nginx+htpasswd实战如果你的机器上安装的是Apache服务，那么htpasswd也许是会附带安装的，但如果你安装的是Nginx服务，那也不用担心，对此我们也可以额外安装这个工具。htpasswd安装htpasswdsudo apt install apache2-utils生成鉴权文件htpasswd -bc .{domain}.pass {username} {password}建议对生成的鉴权文件加上.进行基础隐藏操作，防止被扫描到htpasswd命令详解Nginx配置文件生成鉴权的文件后，我们要对需要加上的server域名下添加以下两条 auth_basic "admin area"; # 启用鉴权 auth_basic_user_file "/etc/nginx/http_auth/.{domain}.pass"; # 指定鉴权文件添加完成后重启服务即可。成果小提示建议对HTTP服务加上SSL证书，以防中间人窃听密码。

【转载】一起来学ES —— 浅谈Nested结构
type: item
date: 2022-05-07T12:12:00+08:00
description: Nested是什么?直观的说，Nested实际上就是Object的数组。如下，这个user就是个nested结构{ "user" : [ { "first" : "John", "last" : "Smith" }, { "first" : "Alice", "last" : "White" } ] }Nested 和 Object 是什么关系？ES原生支持Object类型，也就是任意字段都可以是个对象，而ES又是所有字段都是多值，也就是都可以是list。那么在ES中Nested和Object List又是什么关系呢？这就要从Object说起了。Object虽然是个对象，但是实际存储时是在当前文档里打平存储的。如上那个例子，如果只有一个user，那么在真实索引中实际上是下面这样的{ "user.first" : "John", "user.last" : "Smith" }而如果是个list，那么就成了{ "user.first" : ["John","Alice"], "user.last" : ["Smith","White"] }因为建索引时打平，因此检索时ES就无法知道到底是John Smith还是John White了。因此引入了Nested结构。Nested将list里的每个doc单独变成子文档进行存储，因此在查询时就可以知道具体的结构信息了。Nested 查询要注意什么？Nested因为是单独的子文档存储，因此在使用时，直接用 a.b.c 是无法访问的，需要将其套在nested查询里。除此之外，和其他的查询并无差异。{ "query": { "nested": { "path": "user", "query": { "match": {"user.first" : "John"} }, "inner_hits": {} } } }如上所示，用一个nested套住真实query即可。默认的hit是返回父文档，也就是大的doc。如果加上inner_hits会在父文档的source中多一个inner_hits的字段，返回真实命中的object,其中有个offset表明list数组下标。需要注意的是，由于单独存储很耗资源，因此默认一个index最多只有50个nested字段。此外，虽然nested是单独存储的，但是其字段数也算入index总字段数，默认最多1000个。Nested Aggregation是什么？对于Nested结构，有一点需要谨记的，就是他是个List结构。Nested Agg就是对这个list做agg操作，agg写法和普通的一样，只需要在外面套上nested即可。如官方文档的例子，就是一个商品有许多卖家，对这些卖家的报价求最小值。能否用Nested做动态kv?Nested除了存储固定的Object List,还有一种常用的场景就是用来存储动态的KV。虽然ES天然支持dynamic mapping,但是其key都是固化在每一个doc中的，如果存储用户自定义报表数据。每个用户的key差异很大，放在同一张表会出现大量空值。这是很浪费系统资源的行为，并且随着Key的不断增多，最终会超出index的最大key数量。因此用nested结构来处理这种动态kv就比较合适。 nested的本质就是将 {"tags":{"k1":"v1","k2":"v2"}}=>{"tags":[{"key":"key1","value":"v1"},{"key":"key2","value":"v2"}]}这样一来就可以轻松处理动态kv。并且查询依旧简单，例如k1:v1 AND k2:v2变为{ "query": { "bool": { "must": [ { "nested": { "path": "tags", "query": { "query_string": { "query": "tags.key:k1 AND tags.value:v1" } } } }, { "nested": { "path": "tags", "query": { "query_string": { "query": "tags.key:k2 AND tags.value:v2" } } } } ] } } }动态kv如何做agg呢？普通查询的确很简单，但是agg就并不简单了。原来的模式可以直接用真实字段tags.k1做agg，但是在nested里k1已经变成了一个字段的值，因此没法直接做agg了。这时就需要引入script大法了。其实agg的本质就是从每个doc的正排里取一个值，用这个值做聚合。因此我们只需要用script遍历list，找到对应的key然后返回其value即可。简单写了个如下所示，如果有更好的方法欢迎留言。注意！！！ 由于nes…