🆕add encounter insert with ES
This commit is contained in:
parent
5f0e76c0bb
commit
7ab3cfa81e
@ -64,3 +64,20 @@ func init() {
|
|||||||
log.Fatal(my_errors.ErrorsBasePath)
|
log.Fatal(my_errors.ErrorsBasePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// 1. 初始化程序根目录
|
||||||
|
if curPath, err := os.Getwd(); err == nil {
|
||||||
|
// 路径进行处理,兼容单元测试程序启动时的奇怪路径
|
||||||
|
if len(os.Args) > 1 && strings.HasPrefix(os.Args[1], "-test") {
|
||||||
|
// 替换 \ 为 /,然后移除 /test 及其后的内容
|
||||||
|
curPath = strings.ReplaceAll(curPath, "\\", "/")
|
||||||
|
parts := strings.Split(curPath, "/test")
|
||||||
|
BasePath = parts[0]
|
||||||
|
} else {
|
||||||
|
BasePath = curPath
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Fatal(my_errors.ErrorsBasePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"catface/app/global/variable"
|
"catface/app/global/variable"
|
||||||
"catface/app/http/validator/core/data_transfer"
|
"catface/app/http/validator/core/data_transfer"
|
||||||
"catface/app/model"
|
"catface/app/model"
|
||||||
|
"catface/app/model_es"
|
||||||
"catface/app/service/encounter/curd"
|
"catface/app/service/encounter/curd"
|
||||||
"catface/app/service/upload_file"
|
"catface/app/service/upload_file"
|
||||||
"catface/app/utils/response"
|
"catface/app/utils/response"
|
||||||
@ -67,19 +68,21 @@ func (e *Encounters) Create(context *gin.Context) {
|
|||||||
// STAGE -3: Real Insert - 1: ENC
|
// STAGE -3: Real Insert - 1: ENC
|
||||||
animals_id := data_transfer.GetFloat64Slice(context, "animals_id") // 由于是 Slice 就交给 EAlink 内部遍历时处理。
|
animals_id := data_transfer.GetFloat64Slice(context, "animals_id") // 由于是 Slice 就交给 EAlink 内部遍历时处理。
|
||||||
// Real Insert - 2: EA LINK
|
// Real Insert - 2: EA LINK
|
||||||
if encounter_id, ok := model.CreateEncounterFactory("").InsertDate(context); ok && encounter_id > 0 {
|
if encounter, ok := model.CreateEncounterFactory("").InsertDate(context); ok {
|
||||||
// 2: EA Links
|
// 2: EA Links; // TIP 感觉直接使用 go 会直接且清晰。
|
||||||
if !model.CreateEncounterAnimalLinkFactory("").Insert(int64(encounter_id), animals_id) {
|
go model.CreateEncounterAnimalLinkFactory("").Insert(encounter.Id, animals_id)
|
||||||
response.Fail(context, errcode.ErrEaLinkInstert, errcode.ErrMsg[errcode.ErrEaLinkInstert], errcode.ErrMsgForUser[errcode.ErrEaLinkInstert])
|
// if !model.CreateEncounterAnimalLinkFactory("").Insert(int64(encounter_id), animals_id) {
|
||||||
return
|
// response.Fail(context, errcode.ErrEaLinkInstert, errcode.ErrMsg[errcode.ErrEaLinkInstert], errcode.ErrMsgForUser[errcode.ErrEaLinkInstert])
|
||||||
}
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
// 3. ES speed
|
// 3. ES speed
|
||||||
if level := int(context.GetFloat64(consts.ValidatorPrefix + "level")); level > 1 {
|
if level := int(context.GetFloat64(consts.ValidatorPrefix + "level")); level > 1 {
|
||||||
// TODO
|
go model_es.CreateEncounterESFactory(&encounter).InsertDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Success(context, consts.CurdStatusOkMsg, gin.H{
|
response.Success(context, consts.CurdStatusOkMsg, gin.H{
|
||||||
"encounter_id": encounter_id,
|
"encounter_id": encounter.Id,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg+", 新增错误", "")
|
response.Fail(context, consts.CurdCreatFailCode, consts.CurdCreatFailMsg+", 新增错误", "")
|
||||||
|
@ -44,18 +44,22 @@ func (e *Encounter) TableName() string {
|
|||||||
return "encounters"
|
return "encounters"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encounter) InsertDate(c *gin.Context) (int64, bool) {
|
/**
|
||||||
var tmp Encounter
|
* @description:
|
||||||
|
* @param {*gin.Context} c
|
||||||
|
* @return {*} 返回创建的绑定对象,之后 model_es 的利用。
|
||||||
|
*/
|
||||||
|
func (e *Encounter) InsertDate(c *gin.Context) (tmp Encounter, ok bool) {
|
||||||
if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
|
if err := data_bind.ShouldBindFormDataToModel(c, &tmp); err == nil {
|
||||||
if res := e.Create(&tmp); res.Error == nil {
|
if res := e.Create(&tmp); res.Error == nil {
|
||||||
return tmp.Id, true
|
return tmp, true
|
||||||
} else {
|
} else {
|
||||||
variable.ZapLog.Error("Encounter 数据新增出错", zap.Error(res.Error))
|
variable.ZapLog.Error("Encounter 数据新增出错", zap.Error(res.Error))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
variable.ZapLog.Error("Encounter 数据绑定出错", zap.Error(err))
|
variable.ZapLog.Error("Encounter 数据绑定出错", zap.Error(err))
|
||||||
}
|
}
|
||||||
return 0, false
|
return tmp, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatEncounterList(rows *gorm.DB) (temp []EncounterList, err error) {
|
func formatEncounterList(rows *gorm.DB) (temp []EncounterList, err error) {
|
||||||
|
220
app/model_es/encounter.go
Normal file
220
app/model_es/encounter.go
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
package model_es
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"catface/app/global/variable"
|
||||||
|
"catface/app/model"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/elastic/go-elasticsearch/v8"
|
||||||
|
"github.com/elastic/go-elasticsearch/v8/esapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateEncounterESFactory(encounter *model.Encounter) *Encounter {
|
||||||
|
// 我把数值绑定到了工厂创建当中。
|
||||||
|
return &Encounter{
|
||||||
|
Id: encounter.Id,
|
||||||
|
Title: encounter.Title,
|
||||||
|
Content: encounter.Content,
|
||||||
|
Tags: encounter.TagsSlice, // TODO 暂时没有对此字段的查询。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// INFO 存储能够作为索引存在的数据。
|
||||||
|
type Encounter struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encounter) IndexName() string {
|
||||||
|
return "catface_encounters"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encounter) InsertDocument() error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// 将结构体转换为 JSON 字符串
|
||||||
|
data, err := json.Marshal(e)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建请求
|
||||||
|
req := esapi.IndexRequest{
|
||||||
|
Index: e.IndexName(),
|
||||||
|
DocumentID: fmt.Sprintf("%d", e.Id),
|
||||||
|
Body: bytes.NewReader(data),
|
||||||
|
Refresh: "true",
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
res, err := req.Do(ctx, variable.ElasticClient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if res.IsError() {
|
||||||
|
var e map[string]interface{}
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
|
||||||
|
return fmt.Errorf("error parsing the response body: %s", err)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("[%s] %s: %s",
|
||||||
|
res.Status(),
|
||||||
|
e["error"].(map[string]interface{})["type"],
|
||||||
|
e["error"].(map[string]interface{})["reason"],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encounter) UpdateDocument(client *elasticsearch.Client, encounter *Encounter) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// 将结构体转换为 JSON 字符串
|
||||||
|
data, err := json.Marshal(map[string]interface{}{
|
||||||
|
"doc": encounter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建请求
|
||||||
|
req := esapi.UpdateRequest{
|
||||||
|
Index: encounter.IndexName(),
|
||||||
|
DocumentID: fmt.Sprintf("%d", encounter.Id),
|
||||||
|
Body: bytes.NewReader(data),
|
||||||
|
Refresh: "true",
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
res, err := req.Do(ctx, client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if res.IsError() {
|
||||||
|
var e map[string]interface{}
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
|
||||||
|
return fmt.Errorf("error parsing the response body: %s", err)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("[%s] %s: %s",
|
||||||
|
res.Status(),
|
||||||
|
e["error"].(map[string]interface{})["type"],
|
||||||
|
e["error"].(map[string]interface{})["reason"],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 粗略地包含各种关键词匹配,
|
||||||
|
* @param {*elasticsearch.Client} client
|
||||||
|
* @param {string} query
|
||||||
|
* @return {*} 对应 Encounter 的 id,然后交给 MySQL 来查询详细的信息?
|
||||||
|
*/
|
||||||
|
func (e *Encounter) QueryDocumentsMatchAll(client *elasticsearch.Client, query string) ([]int64, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// 创建查询请求
|
||||||
|
req := esapi.SearchRequest{ // UPDATE 同时实现查询高亮?
|
||||||
|
Index: []string{e.IndexName()},
|
||||||
|
Body: strings.NewReader(fmt.Sprintf(`{
|
||||||
|
"_source": ["id"],
|
||||||
|
"query": {
|
||||||
|
"bool": {
|
||||||
|
"should": [
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"title": "%s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": {
|
||||||
|
"content": "%s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, query, query)),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
res, err := req.Do(ctx, client)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if res.IsError() {
|
||||||
|
var e map[string]interface{}
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing the response body: %s", err)
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("[%s] %s: %s",
|
||||||
|
res.Status(),
|
||||||
|
e["error"].(map[string]interface{})["type"],
|
||||||
|
e["error"].(map[string]interface{})["reason"],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析响应
|
||||||
|
var r map[string]interface{}
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取命中结果
|
||||||
|
hits, ok := r["hits"].(map[string]interface{})["hits"].([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error extracting hits from response")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(hits)
|
||||||
|
|
||||||
|
// 转换为 id 切片
|
||||||
|
var ids []int64
|
||||||
|
for _, hit := range hits {
|
||||||
|
hitMap := hit.(map[string]interface{})["_source"].(map[string]interface{})
|
||||||
|
id := int64(hitMap["id"].(float64))
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids, nil
|
||||||
|
|
||||||
|
// // 转换为 Encounter 切片
|
||||||
|
// var encounters []*Encounter
|
||||||
|
// for _, hit := range hits {
|
||||||
|
// hitMap := hit.(map[string]interface{})
|
||||||
|
// source := hitMap["_source"].(map[string]interface{})
|
||||||
|
|
||||||
|
// // TIP 将 []interface{} 转换为 []string
|
||||||
|
// tagsInterface := source["tags"].([]interface{})
|
||||||
|
// tags := make([]string, len(tagsInterface))
|
||||||
|
// for i, tag := range tagsInterface {
|
||||||
|
// tags[i] = tag.(string)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// encounter := &Encounter{
|
||||||
|
// Id: int64(source["id"].(float64)),
|
||||||
|
// Title: source["title"].(string),
|
||||||
|
// Content: source["content"].(string),
|
||||||
|
// Tags: tags,
|
||||||
|
// }
|
||||||
|
// encounters = append(encounters, encounter)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return encounters, nil
|
||||||
|
}
|
50
test/es/encounter_test.go
Normal file
50
test/es/encounter_test.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"catface/app/global/variable"
|
||||||
|
"catface/app/model"
|
||||||
|
"catface/app/model_es"
|
||||||
|
_ "catface/bootstrap"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEncounterEs(t *testing.T) {
|
||||||
|
// 示例数据
|
||||||
|
encounterOri := &model.Encounter{
|
||||||
|
BaseModel: model.BaseModel{
|
||||||
|
Id: 4,
|
||||||
|
},
|
||||||
|
Title: "猪皮伤势轻,需静养猪皮伤势轻,需静养",
|
||||||
|
Content: "猪皮被带到医院检查了,拍片结果显示损伤不严重,静养即可自愈。建议这段时间不要折腾他,让老登好好休息。",
|
||||||
|
TagsSlice: []string{"猪皮", "脚伤", "骗保"},
|
||||||
|
}
|
||||||
|
|
||||||
|
encounter := model_es.CreateEncounterESFactory(encounterOri)
|
||||||
|
|
||||||
|
// 插入文档
|
||||||
|
// if err := encounter.InsertDocument(); err != nil {
|
||||||
|
// t.Fatalf("插入文档时出错: %s", err)
|
||||||
|
// }
|
||||||
|
go encounter.InsertDocument()
|
||||||
|
|
||||||
|
// // 更新文档
|
||||||
|
// encounter.Content = "更新: 猪皮被带到医院检查了,拍片结果显示损伤不严重,静养即可自愈。建议这段时间不要折腾他,让老登好好休息。"
|
||||||
|
// if err := encounter.UpdateDocument(variable.ElasticClient, encounter); err != nil {
|
||||||
|
// t.Fatalf("更新文档时出错: %s", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 查询文档
|
||||||
|
encounters, err := encounter.QueryDocumentsMatchAll(variable.ElasticClient, "猪皮")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("查询文档时出错: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for _, e := range encounters {
|
||||||
|
// fmt.Printf("ID: %d, 标题: %s, 内容: %s, 标签: %v\n", e.Id, e.Title, e.Content, e.Tags)
|
||||||
|
// }
|
||||||
|
|
||||||
|
for _, e := range encounters {
|
||||||
|
fmt.Printf("ID: %d\n", e)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user