基于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":{}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 恶意挖矿镜像应急实例

01、概述 当网络流量监控发现某台运行多个docker容器的主机主动连接到一个疑似挖矿矿池的地址时,需要快速响应和排查,以阻止进一步的损害。 面对docker容器的场景下,如何快速分析和识别恶意挖矿容器?本文将分享一种应急响应思路,…

kafka 消费者的消费策略以及再平衡1

一kafka 再平衡 1.1 kafka的再平衡 Kafka的再平衡是consumer所消费的topic发生变化时,topic上的分区再次分配的情况。 默认策略是 Range CooperativeSticky 。 Kafka 可以同时使用 多个分区分配策略。 1.2 kafka触发再平衡的情况 1.consumer group中的新增或删…

Godot 和 VScode配置C#环境注意事项

前言 尽管有些博主会建议如果我们熟悉C#的话,最好还是使用GDscript,而且对于小白上手也相对简单,但是C#的性能终究还是比动态语言好,也相比CPP简单些,尽管现在Godot还是有些问题,比如不像unity那样适配swit…

ChatGPT与日本首相交流核废水事件-精准Prompt...

了解更多请点击:ChatGPT与日本首相交流核废水事件-精准Prompt...https://mp.weixin.qq.com/s?__bizMzg2NDY3NjY5NA&mid2247490070&idx1&snebdc608acd419bb3e71ca46acee04890&chksmce64e42ff9136d39743d16059e2c9509cc799a7b15e8f4d4f71caa25968554…

[腾讯云 Cloud Studio 实战训练营] 云上编程的革命:我的 Cloud Studio 体验之旅

文章目录 1. 无缝的云端体验1.1 云端工作站的魅力1.2 真正的在线编程1.3 强大的协作能力1.4 多平台兼容性1.5 安全和数据备份1.6 持续更新和维护1.7 灵活的资源扩展 2. 功能强大的在线 IDE2.1 基础功能全覆盖2.2 高级功能支持2.3 多语言支持2.4 自定义工作流程2.5 版本控制和协…

I/O多路复用三种实现

一.select 实现 (1)select流程 基本流程是: 1. 先构造一张有关文件描述符的表; fd_set readfds 2. 清空表 FD_ZERO() 3. 将你关心的文件描述符加入到这…

数据分享|R语言逻辑回归、线性判别分析LDA、GAM、MARS、KNN、QDA、决策树、随机森林、SVM分类葡萄酒交叉验证ROC...

全文链接:http://tecdat.cn/?p27384 在本文中,数据包含有关葡萄牙“Vinho Verde”葡萄酒的信息(点击文末“阅读原文”获取完整代码数据)。 介绍 该数据集(查看文末了解数据获取方式)有1599个观测值和12个变量&#xf…

ChatGPT的未来

随着人工智能的快速发展,ChatGPT作为一种自然语言生成模型,在各个领域都展现出了巨大的潜力。它不仅可以用于日常对话、创意助手和知识查询,还可以应用于教育、医疗、商业等各个领域,为人们带来更多便利和创新。 在教育领域&#…

安装深度(Deepin)系统

Deepin系统安装 Deepin是和Ubuntu一样,是一个基于Debian的Linux的发型版本。 Deepin相对于Ubuntu,Deepin更适合中国用户的使用习惯。 一 官网工具制作启动盘 制作启动盘、和安装系统,操作非常简单,nice! 官网提供了…

【云计算】虚拟私有网络 VPC

虚拟私有网络 VPC 1.VPC 简介1.1 VPC 相关基本概念1.2 其他相关基本概念 2.VPC 通信场景2.1 VPC 内部互通2.2 VPC 间互通2.2.1 对等连接2.2.2 Transit Gateway 或者云联网 2.3 访问 Internet2.3.1 Internet 网关2.3.2 NAT 网关 2.4 访问本地网络2.4.1 VPN 连接2.4.2 专线接入2.…

uniapp微信小程序地图实现周边

官方说明:小程序JavascriptSDK使用指南 - 微信小程序解决方案 | 腾讯位置服务https://lbs.qq.com/product/miniapp/jssdk/ 先申请腾讯地图的开发者密钥,申请地址:腾讯位置服务 - 立足生态,连接未来 申请密钥时,需要勾…

基于matlab实现的弹簧振动系统模型程序(动态模型)

完整代码: clear all; %System data m1.0; zeta0.01; omega01.0; Dt1.0; f01.0; x00.0; dotx00.0; xmaxsqrt(x0^2(dotx0/omega0)^2)min([0.5*abs(f0)*Dt/(m*omega0) f0/omega0^2]); omegadomega0*sqrt(1-zeta^2); dt00.1*pi/omega0; nstep500; a0.70; b0.…