基于elasticsearch-8.8.2 kibana-8.8.2 搭建一个文搜图系统demo
数据来源是由 图片url,图片descript,图片keywords 外加一个id
基于此首先创建 索引,
keywords是一组由单词或词组 组成的一组数据,所以以数组形式压入数据:
descript 是由两条语句组合成的数据(针对图片的两种不同描述)
# 这里创建的keywords 数组元素类型为text,即可以模糊匹配
PUT /img-search/
{"mappings":{"properties":{"id":{"type": "long"},"keywords":{"type":"text"},"descript":{"type":"text"},"url":{"type":"keyword"}}}
}
#这里创建的keywords 数组元素为keyword ,只能是精确匹配数组中的元素
PUT /pic-search/
{"mappings":{"properties":{"id":{"type": "long"},"keywords":{"type":"keyword"},"descript":{"type":"text"},"url":{"type":"keyword"}}}
}
然后倒入提前准备好的数据:
curl -X POST "http://121.36.xxx.xx:xxxx/img-search/_bulk" -H "Content-Type: application/json" --data-binary "@data.json"
data.json 文件的内容如下:
# 格式需要严格按照如下形式
{"index":{"_index":"img-search","_id":"002"}}
{"id":1,"keywords":["fly","wing","bird","crane","egret","stretch","flight","large","spread","white","heron","beak","sky","cloudy"],"descript":"'white bird in flight over a grey background', 'white bird in flight on a white background'","url":"baidu.com"}
清空img-search 索引下的数据:
#kibana 界面操作
POST /img-search/_delete_by_query
{"query":{"match_all":{}}
}
在Elasticsearch中,处理某个字段有多个值的情况可以采用不同的方法,具体取决于你的查询需求以及数据的性质。以下是两种主要的方法
1.数组字段:将该字段创建为一个数组(或者Elasticsearch中的nested字段,更复杂的数据结构)。这种方法适用于字段的多个值之间具有关联性,你希望能够对这些值进行聚合、过滤和查询。例如,如果你有一个文档表示一本书,可以将作者字段设计为数组,以便容纳多位作者。
优点:
可以使用Elasticsearch的聚合功能对多个值进行分析。
可以更容易地进行复杂的查询,例如搜索包含指定作者的所有书籍。
缺点:
使用数组会增加索引的复杂性和存储开销

2.多个字段串连接:将多个值连接成一个长字符串,并将其作为单个字段存储。这种方法适用于字段的多个值之间没有关联性,或者你只关心字段的文本表示形式。你可以使用分隔符将多个值连接在一起。
优点:
索引和存储开销较低。
可以简化索引映射和查询。
缺点:
不适用于需要对多个值进行聚合或复杂查询的情况。

所以考虑到后期可能会对图片提取词进行聚合分类查询
这里选择数组类型存储keywords
#从指定API拉取图片
func mainDownload() {for _, p := range [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} {url := "http://www.xxx.com/getPhotoByKeywords?keyword=人物&cate=3&page=" + strconv.Itoa(p) // 替换为你要请求的 URL// 发起 GET 请求response, err := http.Get(url)if err != nil {fmt.Println("请求失败:", err)return}defer response.Body.Close()// 读取响应数据body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("读取响应数据失败:", err)return}type image struct {Id int `json:"id"`Title string `json:"title"`KeywordTags string `json:"keywordTags"`Url string `json:"url"`Cate int `json:"cate"`}type respStruct struct {Code int `json:"code"`Msg string `json:"msg"`Data []image `json:"data"`}// 打印响应数据fmt.Println("响应数据:")var r respStructerr = json.Unmarshal([]byte(body), &r)if err != nil {fmt.Println("json.Unmarshal", err)}//fmt.Println(r)//trans := &http.Transport{}for _, v := range r.Data {fmt.Println(v.Url, len(v.Url))re, err := http.NewRequest("GET", "https:"+v.Url, nil)if err != nil {fmt.Println("http.NewRequest err:", err)}fmt.Println("http.NewRequest url:", v.Url)re.Header.Set("Referer", "https://www.51mo.com")client := http.Client{}resp, err := client.Do(re)if err != nil {fmt.Println("client.Do image:", err)}defer resp.Body.Close()sindex := strings.Index(v.Url, ".com")eindex := strings.Index(v.Url, "?")fmt.Println("sindex_eindex:", sindex, eindex)fmt.Println(v.Url[sindex+5 : eindex])fileName := strings.Replace(v.Url[sindex+5:eindex], "/", "+", -1)// 创建图片文件file, err := os.Create("./pic/" + fileName)if err != nil {fmt.Println("os.Create err:", err)}defer file.Close()_, err = io.Copy(file, resp.Body)if err != nil {fmt.Println("io.Copy err:", err)}}}
}#将模型转化来的数据从excel 中读取出来写入data.json 文件作为写入es 的数据
func mainFormatData() {// 打开Excel文件xlFile, err := xlsx.OpenFile("shang.xlsx")if err != nil {log.Fatal(err)}// 遍历工作表for _, sheet := range xlFile.Sheets {fmt.Printf("工作表名称: %s\n", sheet.Name)// 遍历行for numIndex, row := range sheet.Rows {// 遍历单元格var key, keyval, descval, nameval stringfor columnIndex, cell := range row.Cells {if columnIndex == 0 {continue}text := cell.String()switch columnIndex {case 1:key = "keywords"//keyval = strings.Replace(text, `"`, `'`, -1)re := regexp.MustCompile(`([a-zA-Z])"([a-zA-Z])`)keyval = re.ReplaceAllString(text, "$1'$2")case 2:key = "descript"//descval = strings.Replace(text, `"`, `'`, -1)#下面这里将左右两边都是字母的双引号换为单引号re := regexp.MustCompile(`([a-zA-Z])"([a-zA-Z])`)descval = re.ReplaceAllString(text, "$1'$2")case 3:key = "name"nameval = text}fmt.Printf("第 %d 个 %s :%s\t", numIndex, key, text)}_num := numIndex + 801_i := map[string]any{"index": map[string]string{"_index": "img-search","_id": strconv.Itoa(_num),},}fmt.Println("descval", descval)_v := map[string]any{"id": _num,"keywords": keyval,"descript": descval,"name": nameval,}_jsonI, err := json.Marshal(_i)if err != nil {log.Fatal("json.Marshal I err:", err)}_jsonV, err := json.Marshal(_v)if err != nil {log.Fatal("json.Marshal V err:", err)}file, err := os.OpenFile("data.json", os.O_WRONLY|os.O_APPEND, 0666)if err != nil {log.Fatal("os.OpenFile err:", err)}defer file.Close()write := bufio.NewWriter(file)_g := strings.Replace(string(_jsonV), `\"`, `"`, -1)_y := strings.Replace(_g, `"[`, `[`, -1)_z := strings.Replace(_y, `]"`, `]`, -1)write.WriteString(string(_jsonI) + "\n")write.WriteString(_z + "\n")write.Flush()fmt.Println("\n")}}
}
最终data.json 中的数据如下:
{"index":{"_id":"1","_index":"img-search"}}
{"descript":["woman holding a yellow maple leaf on an orange background", "a smiling young woman with a yellow maple leaf"],"id":1,"keywords":["hold", "girl", "hand", "red", "autumn", "young", "leaf", "woman", "smile", "catch", "sweater", "face", "maple leaf", "autumn leave", "laugh", "yellow"],"name":"ai+upload+20230721+edit_cMSndoSirkfboFoQ.jpg"}
{"index":{"_id":"2","_index":"img-search"}}
{"descript":["group of people looking at the world around them", "group of people facing the earth, with some galaxy background"],"id":2,"keywords":["stand", "business suit", "earth", "world", "businessman", "man", "people", "person", "purple"],"name":"ai+upload+20230726+edit_0W7yMVLHVtVTLfcf.jpg"}
通过API接口将data,json 中的数据写入es
curl -X POST "http://121.36.xxx.xx:9201/img-search/_bulk" -H "Content-Type: application/json" --data-binary "@data.json"
#查看es某条索引下有多少数据,以及最大的文档ID/如果数据量正好等于最大文档ID 则说明导入数据没有缺失
GET /img-search/_search
{"aggs": {"max_id": {"max": {"field": "id"}}},"size": 0
}
#清空某条索引下所有的数据
POST /img-search/_delete_by_query
{"query":{"match_all":{}}
}
相关文章:
基于elasticsearch-8.8.2 kibana-8.8.2 搭建一个文搜图系统demo
数据来源是由 图片url,图片descript,图片keywords 外加一个id 基于此首先创建 索引, keywords是一组由单词或词组 组成的一组数据,所以以数组形式压入数据: descript 是由两条语句组合成的数据(针对图片的两种不同描述) # 这里创建的keywords 数组元素类型为text,即可以模糊匹…...
第26节-PhotoShop基础课程-形状工具组-画板
文章目录 前言1.基础图形1.正方形(shift/alt/两者加起来)2.描边3.合并形状 将多个图放在一个图层4.对齐只能在不同图层5.修改6.重叠,相交 2.多边形1.边数2.星形 3.直线工具1.正常2.箭头 4.自定义形状 前言 类似画图板,矢量图形。…...
第一次课,通过进程信息和服务信息识别当前计算机运行程序(预习版)
题目: 检测的目标进程: ydebugg ; “ImmunityDebugger.exe” _500], rax Exe ; “ollydbg.exe” _4F8], rax hackerE ; “ProcessHacker.exe” _4F0], rax Exe ; “tcpview.exe” _4E8], rax sExe ; “autoruns.exe” _4E0], rax scExe ; “autorunsc.ex…...
ChatGPT 或其它 AI,能用在文书创作上吗?
新的申请季已经正式开始,一些热门项目的ED截止日期也不再遥远,因此很多准留学生们都已经开始了关于文书的创作。 而随着科技的不断发展,以ChatGPT为首的一众AI工具也作为一种辅助手段愈发融入了我们的生活。 那么不免就会有一些同学在准备申…...
Java中锁的分类
Java中锁的分类 这篇文章介绍各种锁的分类。介绍的内容如下: 公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重量级锁自旋锁 上面是很多锁的名词,这些分类并不是全是指锁的状态,有的指锁的特性&am…...
centos安装flink,通过windows访问webui
1. 安装flink 1.1. flink的下载 通过flink官网下载flink安装包 https://flink.apache.org/ 下载安装包 1.2 flink在centos上的安装 将下载好的flink-1.17.1-bin-scala_2.12.tgz安装包放到centos目录下 解压文件: [rootlocalhost ~]# tar -zxvf flink-1.17.…...
如何让两台手机相互远程控制?
你的两台手机是什么系统的?如果你的两台手机都是安卓系统,而且都是安卓7.0及以上版本的系统,那么恭喜你,这两台手机可以相互远程控制! 你可以利用两个软件实现将两台手机相互远程控制的想法。为了避免混淆,…...
预编译为什么能防止SQL注入?一看你就明白了。预编译原理详解
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 预编译防止SQL注入 1、SQL执行过程2、预编译原理3、…...
【7z密码】7z压缩包密码忘记了,怎么办?i
7z压缩包设置了密码,解压的时候就需要输入正确对密码才能顺利解压出文件,正常当我们解压文件或者删除密码的时候,虽然方法多,但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么,忘记了7z压缩包的密码…...
部署云MYSQL(在线版)
在Methodot - 您的一站式云原生在线开发协作平台网站上可以部署免费的MYSQL,在应用商店里能看到可以搭建多种数据库:(前提是要注册登录,免费版只能是2人共享) 登陆好后,点击工作台,选择应用商店…...
Gin 框架 解决 跨域问题
Gin 框架解决跨域问题 一点废话 在学习 Axios 的时候发现 up 使用了一个网址来提供 json 数据。因为不想加什么公众号搞啥百度网盘的,然后又刚好会一点点 go,就想着自己用 gin 框架返回一个 json 到前端页面然后从这个页面获取 json 。 这是我的go代码…...
【Datawhale课程笔记-简单学点大模型】大模型的能力
大模型的能力 参考GITHUB:https://github.com/datawhalechina/so-large-lm/blob/main/第二章:大模型的能力.md 深入探讨GPT-3——这个具有代表性的大型语言模型的能力。我们的研究主要基于GPT-3论文中的基准测试,这些测试包括: …...
git使用说明
目录 前言1.安装1.1. windows1.1.1.git客户端1.1.2.配置git客户端1.1.3.安装TortoiseGit图形客户端1.1.4 关于文件换行问题 1.2.ubuntu1.2.1.ubuntu终端Git中文乱码1.2.2 git log中文乱码解决 2.建立版本库2.1.下载网上开源版本库2.1.1.复制下载地址2.1.2.使用命令行…...
【PowerQuery】PowerBI Pro账户的自动刷新
在数据和模型通过发布或者上传方式上传到PowerBI Pro中,如何来进行数据刷新呢?数据源依然在本地,而数据模型已经发布到PowerBI Pro云端服务中。如果数据源更新,我们的模型如何进行自动刷新呢? PowerBI Pro如果需要基于本地数据源更新进行模型更新需要部署相应的数据网关服…...
红黑树(思维导图详解版)
目录 资源已上传 实现代码 测试代码 资源已上传 部分图片 实现代码 注意判断是否为红黑树的代码实现,实现代码中红黑树的删除 #pragma once #include<iostream> using namespace std;enum Color_Type {Red,Black };template<class K,class V> str…...
javafx学习记录
1.布局 2.选择重写或实现方法(select methods to override/implements) ctrl o 3.javafx有init方法,start方法,stop方法 4.定义一个按钮,使用系统默认浏览器访问网站 5.使窗口的关闭栏,缩小扩屏栏,代码是倒数第二行 6.设置模态窗口,默认关闭模态的 下…...
友善Nona Pi开发板ubuntu22.04系统用Python3.8.17的pip安装PyQt5.15.2时报错“Q_PID”这个宏未定义的一种解决办法
安装命令: pip install PyQt55.15.2 --config-settings --confirm-license --verbose -i https://mirrors.aliyun.com/pypi/simple/ 遇到出错: 如图: 分析具体错误内容: These bindings will be built: Qt, QtCore, QtNetwo…...
HTML中name和class,id的区别和联系
在HTML中,name、class和id是用于标识和选择元素的属性。 区别: name属性:用于标识表单元素,特别是在提交表单时,用于识别表单数据。name属性可以在同一表单中的多个元素中重复使用。class属性:用于为一个…...
Google 开源库Guava详解(集合工具类)—Maps、Multisets、Multimaps
一、Maps Maps有许多很酷的实用程序,值得单独解释。 1、uniqueIndex Maps.uniqueIndex(Iterable,Function)解决了一个常见的情况,即有一堆对象,每个对象都有一些唯一的属性,并希望能够根据该…...
肖sir__mysql之介绍__001
mysql之介绍 一、认识数据库 (1)什么是数据库? 是存放数据的电子仓库。以某种方式存储百万条,上亿条数据,供多个用户访问共享。 如: (2)数据库分关系型数据库和非关系型数据库 a、…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
