Elasticsearch + Search UI 构建一个文件搜索引擎
目录
- Elasticsearch
- 使用优势
- App Search
- Search UI
- 配置engine
- 集中管理配置和提供实用工具函数
- 配置和初始化一个基于Elasticsearch的搜索界面应用程序
- Search UI 基础用法
- 好书推荐

Elasticsearch
使用优势
使用ElasticSearch的主要好处在于其强大的全文搜索和实时分析能力。ElasticSearch基于Apache Lucene构建,提供了高性能、可扩展的搜索解决方案,支持复杂的搜索查询,如模糊搜索、全文搜索、多字段搜索、地理空间搜索等。它能够自动处理文本分析,如分词、索引和查询优化,从而极大地提升了搜索速度和准确性。此外,ElasticSearch支持分布式部署,能够轻松处理PB级数据,保证了系统的高可用性和可扩展性。无论是用于构建搜索引擎、日志分析、实时监控还是其他需要高效搜索和分析的场景,ElasticSearch都能提供强大的技术支持和灵活的配置选项,帮助用户快速响应业务需求。
初步使用Elasticsearch包括下面的步骤
- 运行 Elasticsearch 和 Kibana(使用 Elastic Cloud 或在本地 Docker 开发环境中),
- 向 Elasticsearch 添加简单(无时间戳)数据集,
- 运行基本搜索。
Elasticsearch 入门指南
App Search
App Search 建立在 Elasticsearch 之上,为您的应用程序提供丰富的开箱即用搜索功能。App Search 包括:
- 一组用于提取内容的 RESTful API
- 直观的仪表板
- 实时搜索查询和点击分析
- 查询相关性调整
- 支持查询同义词
- 支持语言优化引擎
- 支持 API 客户端
Search UI
Search UI 是一个基于React 实现的一套UI框架(可以嵌套在任何JS框架,包括Vue框架)用于使用Elastic快速开发现代、引人入胜的搜索体验。无需重新设计轮子,即可快速启动并运行。
vue版本案例
Search UI入门指南
使用App Search创建Search UI
Search UI API
注意:使用官方vue版本,需要用特定的class 对ES返回的<em>
标签进行设置。
配置engine
Elasticsearch查询的JSON配置,如引擎名称、端点基础、搜索密钥、结果字段、排序字段、过滤器、标题字段和URL字段。
{"engineName": "es-plugins-file",//引擎名称"endpointBase": "/elastic_serve",//查询的基础URL部分"searchKey": "",//搜索密钥"resultFields": [//结果字段"actLine","classId","deptId","className","deptName","stuName","fileContent","fileName","filePath","fileType","fileUrl","parentId","stuId","uploadDate","uploadDateStr","uploadTime","uploadTimeStr","id"],"sortFields": [//排序字段"uploadTime"],"facets": [//过滤器"uploadDate","classId","deptId"],"titleField": "fileName",//标题字段"urlField": "fileUrl"//URL字段
}
集中管理配置和提供实用工具函数
import config from "./engine.json";
export function getConfig() {if (process.env.NODE_ENV === "test") {return {};}if (config.engineName) return config;if (typeof window !== "undefined" &&window.appConfig &&window.appConfig.engineName) {return window.appConfig;}return {};
}
//处理字符串
function toLowerCase(string) {if (string) return string.toLowerCase();
}function capitalizeFirstLetter(string) {return string.charAt(0).toUpperCase() + string.slice(1);
}
//获取标题字段
export function getTitleField() {// If no title field configuration has been provided, we attempt// to use a "title" field, if one existsreturn getConfig().titleField || "title";
}
//获取URL字段
export function getUrlField() {return getConfig().urlField;
}
//获取缩略图字段
export function getThumbnailField() {return getConfig().thumbnailField;
}
//获取过滤字段
export function getFacetFields() {return getConfig().facets || [];
}
//获取排序字段
export function getSortFields() {return getConfig().sortFields || [];
}
//获取结果标题
export function getResultTitle(result) {const titleField = getTitleField();return result.getSnippet(titleField);
}//剔除不必要的结果字段。从结果字段中剔除不需要显示的字段,例如已配置为“标题”显示的字段。
export function stripUnnecessaryResultFields(resultFields) {return Object.keys(resultFields).reduce((acc, n) => {if (["_meta","id",toLowerCase(getTitleField()),toLowerCase(getUrlField()),toLowerCase(getThumbnailField()),].includes(toLowerCase(n))) {return acc;}acc[n] = resultFields[n];return acc;}, {});
}
//建搜索选项
export function buildSearchOptionsFromConfig(dateRange = null) {const config = getConfig();console.log('1123123123123123213213', config.searchFields, config.fields)const searchFields = (config.searchFields || config.fields || []).reduce((acc, n) => {acc = acc || {};acc[n] = {};return acc;},undefined);const resultFields = (config.resultFields || config.fields || []).reduce((acc, n) => {acc = acc || {};acc[n] = {raw: {},snippet: {size: 100,fallback: true}};return acc;},undefined);if (config.urlField) {resultFields[config.urlField] = {raw: {},snippet: {size: 100,fallback: true}};}if (config.thumbnailField) {resultFields[config.thumbnailField] = {raw: {},snippet: {size: 100,fallback: true}};}if (config.titleField) {resultFields[config.titleField] = {raw: {},snippet: {size: 100,fallback: true}};}const searchOptions = {};searchOptions.result_fields = resultFields;searchOptions.search_fields = searchFields;return searchOptions;
}//构建过滤配置
export function buildFacetConfigFromConfig() {const config = getConfig();const facets = (config.facets || []).reduce((acc, n) => {acc = acc || {};acc[n] = {type:'value',size:100}return acc;}, undefined);return facets;
}//构建排序选项
export function buildSortOptionsFromConfig() {const config = getConfig();return [{name: "Relevance",value: "",direction: ""},...(config.sortFields || []).reduce((acc, sortField) => {acc.push({name: `${capitalizeFirstLetter(sortField)} ASC`,value: sortField,direction: "asc"});acc.push({name: `${capitalizeFirstLetter(sortField)} DESC`,value: sortField,direction: "desc"});return acc;}, [])];
}
//构建自动完成查询配置
export function buildAutocompleteQueryConfig() {const querySuggestFields = getConfig().querySuggestFields;if (!querySuggestFields ||!Array.isArray(querySuggestFields) ||querySuggestFields.length === 0) {return {};}return {suggestions: {types: {documents: {fields: getConfig().querySuggestFields}}}};
}
配置和初始化一个基于Elasticsearch的搜索界面应用程序
使用了@elastic/search-ui-app-search-connector来连接到Elasticsearch,并通过一系列的配置函数来设置搜索参数、自动完成查询、过滤器(facets)和排序选项。
//导入必要的模块:包括regenerator-runtime/runtime以支持异步操作,AppSearchAPIConnector用于连接到Elasticsearch,以及从./config-helper导入的配置构建函数。
import "regenerator-runtime/runtime";
import AppSearchAPIConnector from "@elastic/search-ui-app-search-connector";import {buildAutocompleteQueryConfig,buildFacetConfigFromConfig,buildSearchOptionsFromConfig,buildSortOptionsFromConfig,getConfig,getFacetFields
} from "./config-helper";//获取配置:通过getConfig函数获取应用程序的配置,包括搜索密钥(searchKey)、引擎名称(engineName)、主机标识符(hostIdentifier)和基础URL(endpointBase)。const { hostIdentifier, searchKey, endpointBase, engineName } = getConfig();
//初始化API连接器:使用AppSearchAPIConnector创建一个新的连接器实例,传入必要的配置参数。
const connector = new AppSearchAPIConnector({searchKey,engineName,hostIdentifier,endpointBase
});//构建配置对象:构建一个配置对象,其中包含搜索查询的配置、自动完成查询的配置、API连接器实例、以及其他相关设置,如是否在初始加载时总是执行搜索、是否跟踪URL状态。
const config = {searchQuery: {facets: buildFacetConfigFromConfig(),...buildSearchOptionsFromConfig()},autocompleteQuery: buildAutocompleteQueryConfig(),apiConnector: connector,alwaysSearchOnInitialLoad: false,//设置为false意味着在组件首次加载时不会自动触发搜索,需要用户手动触发搜索或者在加载完成后根据其他条件动态决定是否搜索的场景。trackUrlState: false,// 禁用 URL 状态跟踪};export default config;
Search UI 基础用法
SearchDriver是一个用于集成Elasticsearch搜索功能到Vue应用程序的工具,用来初始化和管理搜索功能。config是之前定义的配置对象,包含了所有必要的设置以支持搜索操作。
import { SearchDriver } from "@elastic/search-ui";
创建SearchDriver的实例,并将之前构建的配置对象传递给它。这样做的目的是将配置好的搜索功能集成到Vue应用程序中,SearchDriver可能负责处理搜索请求、更新搜索结果、管理状态等任务。
const driver = new SearchDriver(config);
- subscribeToStateChanges
订阅搜索状态变化的事
driver.subscribeToStateChanges(state => {// 搜索状态发生变化时,打印新的状态对象并执行相应的操作。this.searchState = state;});
- getState
这个方法通常用于获取当前搜索状态,包括搜索参数、过滤条件、排序选项等信息。
const {searchTerm,//搜索查询的关键词或短语。resultsPerPage,//每页显示的搜索结果数量。filters,//应用的过滤器列表。facets//可用于搜索结果细分的分面(facet)信息。} = driver.getState();
- reset
用于重置搜索状态到初始状态,清除所有之前的搜索参数、过滤条件和排序选项。
driver.reset();
- clearFilters
用于清除所有当前应用的过滤条件,但不会重置其他搜索状态,如搜索关键字或排序选项。
driver.clearFilters();
- getActions().setSearchTerm();
调用SearchDriver实例的getActions方法来获取一个操作对象,然后通过这个操作对象设置搜索关键字。 - setCurrent
跳转到第几页
driver.setCurrent();
-
getState().facets
用于读取当前搜索状态中的特定信息 -
removeFilter
从当前的搜索状态中移除过滤条件
driver.removeFilter('classId');
- addFilter
向当前的搜索状态中添加过滤条件
driver.addFilter('classId',"具体值", "any");
好书推荐
《区块链编程》
区块链技术远超比特币背后的技术范畴,其概念实际上十分广泛。它凭借坚不可摧的安全性、去中心化交易以及可独立验证的供应链,已经彻底改变了货币、数字身份和物流等领域。借助以太坊和超级账本等平台,开发者可以利用熟悉的编程语言轻松上手区块链项目。
《区块链编程》以简明扼要的方式,教会读者如何设计和构建基于区块链的去中心化应用程序。首先,你将全面了解区块链的工作原理。随后,你将使用以太坊和Solidity编写你的首个智能合约。接着,你将逐步添加Web界面、信任验证等功能,直至准备好应用程序的部署。你只需配置好标准硬件和利用开源软件,便可轻松启程,踏上区块链编程的探索之旅。
相关文章:

Elasticsearch + Search UI 构建一个文件搜索引擎
目录 Elasticsearch使用优势App Search Search UI配置engine集中管理配置和提供实用工具函数配置和初始化一个基于Elasticsearch的搜索界面应用程序Search UI 基础用法 好书推荐 Elasticsearch 使用优势 使用ElasticSearch的主要好处在于其强大的全文搜索和实时分析能力。Elas…...

机械学习—零基础学习日志(如何理解概率论2)
全概率公式与贝叶斯公式 上面所提到的公式,可以使用上一篇文章的基本公式推导。 使用到了概率的基本运算公式。 完整的公式展示: 习题练习: 剩余的练习: 第二题解析: 第三题: 第四题: 注意&…...

鸿蒙关于手机全局本地文件读取,写入
一.背景 需求是需要操作用户手机中的文件,不是应用沙箱 二.解决方案 这里要注意的一点拿到fsOpen.path的路径再去进行open文件,因为这里还不知道本地文件路径在哪里,需要选择一下路径再拿到路径去请求 1.这里就是进行两个fs.open…...

嵌入式企业面试真题
1.C语言中指针数组和数组指针的区别是什么? 答:指针数组是指数组的元素都是指针类型的数组。数组指针是指一个指向数组的指针。指向的是数组第一个元素的地址,每次偏移一个数组的大小。 2.讲一下什么是结构体字节对齐? 答:结构体字节对齐是指当结构体中元素的物理内存大…...

开源一款H5自适应留言表白墙php源码下载
开源一款H5自适应留言表白墙php源码下载,优点就是安装简单,功能实用[滑稽][滑稽] 缺点就是UI简陋,功能稀少 第一张是首页,第二张是查看留言 第三张是留言列表(10秒自动刷新),第四张是表白墙界面...

jmeter引入jar包的三种方式
示例 实现对登录密码进行MD5加密 pom文件依赖 <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.12&l…...

零基础学习Redis(5) -- redis单线程模型介绍
前面我们提到过,redis是单线程的,这期我们详细介绍一下redis的单线程模型 1. redis单线程模型 redis只使用一个线程处理所有的请求,并不是redis服务器进程内部只有一个线程,其实也存在多个线程,只不过多个线程是在处…...

Android Audio
audio概述: Android Audio知识梳理 看完这一篇就够了!-CSDN博客 Android audio篇章(1)------Audio架构_android audio(1)-CSDN博客 android audio google: 音频 | Android Open Source Project (google.cn) 音频…...

远程MySQL数据库:定义、优势及cPanel的数据库工具
在现代网站和应用程序开发中,数据库是必不可少的核心部分。通常情况下,数据库与网站托管在同一台服务器上,但为了提升性能和安全性,越来越多的用户选择使用远程MySQL数据库。那么,什么是远程MySQL数据库呢?…...

【docker】Dockerfile
Dockerfile是用于构建Docker镜像的文本文件,其中包含一组用于定义镜像构建过程的指令。下面是常见的Dockerfile指令及其解释: FROM:指定基础镜像,用于构建新镜像。COPY:将文件或目录从构建上下文复制到镜像中。ADD&am…...

Redis 的 List 结构非常适合用于实现消息队列php
1. Redis List 结构消息队列简介 Redis 的 List 结构非常适合用于实现消息队列。你可以通过 LPUSH 或 RPUSH 命令将消息推入队列,通过 BLPOP 或 BRPOP 命令从队列中弹出消息。BLPOP 和 BRPOP 命令支持阻塞操作,适合在消费者端等待消息的到来。 2. 实现…...

极速闪存启动:SD与SPI模式的智能初始化指南
最近很多客户朋友在询问我们 CS 创世 SD NAND 能不能使用 SPI 接口,两者使用起来有何区别,下面为大家详细解答。 SD MODE: CS 创世 SD NAND 支持 SD 模式和 SPI 模式,SD NAND 默认为 SD 模式,上电后,其初始化过程如下…...

利用多Lora节省大模型部署成本|得物技术
一、背景 近期,我们在大模型集群的部署过程中遇到了一些挑战。公司有多个业务场景,每个场景都基于自身的数据进行微调,训练出相应的大模型并上线。然而,这些场景的调用量并不高,同时大模型的部署成本较为昂贵…...

使用SSMS连接和查询 SQL Server 实例
简介 SQL Server Management Studio 是用于管理SQL Server基础架构的集成环境。Management Studio提供用于配置、监视和管理SQL Server实例的工具。 此外,它还提供了用于部署、监视和升级数据层组件(如应用程序使用的数据库和数据仓库)的工具以生成查询和脚本。 官方…...

HarmonyOS Next原生应用开发-从TS到ArkTS的适配规则(十五)
一、不支持for … in 规则:arkts-no-for-in 级别:错误 由于在ArkTS中,对象布局在编译时是确定的、并且不能在运行时被改变,所以不支持使用for … in迭代一个对象的属性。对于数组来说,可以使用常规的for循环。TypeScri…...

两个系统之间跳转免密登录
1、 两个系统之间跳转免密登录_从一个系统跳转到另一个系统,不用再重新登录-CSDN博客 2、 页面跳转统一登录实现_前端从一个系统跳转到其他系统-CSDN博客...

SQL基础——MySQL的触发器、存储引擎、事务
简介:个人学习分享,如有错误,欢迎批评指正。 一、MySQL的触发器 1.概述 介绍 触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段,但是触发器无需调用&…...

目标检测算法:对比YOLOv3、YOLOv5、YOLOv8
目标检测 YOLOv3 数据处理 可输入任意大小的图片(特征图大小最好是32倍数)Anchor:K-Means聚类IOUNMS 模型结构 Backbone Darknet53 无最大池化,步长2卷积层进行下采样每个Conv后 BN LeakyReLU引入残差结构中间层和某一层上…...

C# 属性(Property)
C# 属性(Property) C# 中的属性(Property)是一种用于访问和设置类或结构体成员的值的特殊成员。属性提供了一种封装字段的方式,使得字段的访问更加安全和灵活。本文将详细介绍 C# 属性的概念、用途、语法以及如何使用…...

3. 数据结构——栈的操作实现
1. 顺序栈 主要操作:初始化、栈判空、入栈、出栈、去栈顶元素 1.1 直接数组存储栈 //顺序栈的实现 #include<stdio.h> #define MaxSize 50 typedef int ElemType; typedef struct{ElemType data[MaxSize];int top; //指向栈顶指针,最开始-1 …...

EmguCV学习笔记 VB.Net 4.5 像素距离和连通区域
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 教程VB.net版本请访问:EmguCV学习笔记 VB.Net 目录-CSDN博客 教程C#版本请访问:EmguCV学习笔记 C# 目录-CSD…...

使用spring boot开发与直接开发一个web项目的区别
1. 项目结构的区别 springboot开发没有web.xml,配置更加简洁。 2. 启动 传统的web项目将项目打成war包,然后将war包复制到tomcat的webapp目录下,最后通过启动tomcat部署运行项目。 而springboot将项目打成jar包,jar包中包含内置的…...

Leetcode JAVA刷刷站(48)旋转图像
一、题目概述 二、思路方向 要在原地顺时针旋转一个 n x n 的二维矩阵 90 度,你可以通过一系列交换操作来实现。这里的关键在于理解旋转后的矩阵与原矩阵之间的元素对应关系。 假设原矩阵为 matrix,其中 matrix[i][j] 表示第 i 行第 j 列的元素。旋转 90…...

编译型语言和解释型语言
年代区分 从硬件技术和软件需求,计算机发展初期,没有可能发展真正的解释型语言,运行速度和内存都受限,只有给机器喂二进制代码才能勉强跑起来。但事实上,解释型语言却在计算机发展很早的时期曾经出现过,当…...

TensorRT 和 PyTorch区别
一、TensorRT 和 PyTorch TensorRT 和 PyTorch 是两个不同的深度学习工具,虽然它们可以用于处理相同类型的任务,但它们的用途、特点和设计目标有所不同。 TensorRT 简介 TensorRT 是 NVIDIA 开发的一款高性能深度学习推理引擎,主要用于优化…...

iOS 17.6.1版本重发,修复高级数据保护错误
今日,苹果没有带来iOS 17.6.2的更新,而是重新发布了iOS 17.6.1版本,本次升级版本号为21G101,高于第一版的21G93。距离初版发布相隔一周半时间。 在 iOS / iPadOS 17.6.1 的更新日志,苹果公司写道:“此更新包…...

【排序算法】八大排序(上)(c语言实现)(附源码)
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:算法 目录 前言 写一串测试数据 交换两元素的函数 一、冒泡排序 二、选择排序 三、插入排序 四、希尔排序 程序全部代码 总结 前言 排序算法是计算机科…...

Python版《超级玛丽+源码》-Python制作超级玛丽游戏
小时候最喜欢玩的小游戏就是超级玛丽了,有刺激有又技巧,通关真的很难,救下小公主还被抓走了,唉,心累,最后还是硬着头皮继续闯,终于要通关了,之后再玩还是没有那么容易,哈…...

互联网私有IP地址列表
最近因为业务需要,要判断用户的IP是否私有IP, 以前知道的私有IP,基本上只有如下几个(注意:这不是正确答案): 10.0.0.0/8(10.0.0.0-10.255.255.255)172.16.0.0/12(172.16.0.0-172.31…...

光伏项目管理软件为什么那么多光伏人在用?
在光伏行业迅速发展的今天,光伏项目管理软件已成为众多光伏从业者不可或缺的得力助手。那么,为何这款软件能够受到如此广泛的青睐和应用呢? 一、提高项目管理效率 光伏项目管理软件通过数字化、智能化的手段,对光伏项目的各个环节…...