数据来源是由 图片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 respStruct
err = 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("pic.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 string
for columnIndex, cell := range row.Cells {
if columnIndex == 0 {
continue
}
text := cell.String()
switch columnIndex {
case 1:
key = "keywords"
keyval = text
case 2:
key = "descript"
descval = text
case 3:
key = "name"
nameval = text
}
fmt.Printf("第 %d 个 %s :%s\t", numIndex, key, text)
}
_num := numIndex + 1
_i := map[string]any{
"index": map[string]string{
"_index": "img-search",
"_id": strconv.Itoa(_num),
},
}
_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
GET /img-search/_search
{
"aggs": {
"max_id": {
"max": {
"field": "id"
}
}
},
"size": 0
}
#清空某条索引下所有的数据
POST /img-search/_delete_by_query
{
"query":{
"match_all":{}
}
}