🆕finish half knowledge ES
This commit is contained in:
parent
5c2536a3a7
commit
9de43d0d09
1
app/model_es/animal.go
Normal file
1
app/model_es/animal.go
Normal file
@ -0,0 +1 @@
|
||||
package model_es
|
144
app/model_es/knowledge.go
Normal file
144
app/model_es/knowledge.go
Normal file
@ -0,0 +1,144 @@
|
||||
package model_es
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"catface/app/global/variable"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/elastic/go-elasticsearch/v8/esapi"
|
||||
)
|
||||
|
||||
func CreateKnowledgeESFactory() *Knowledge {
|
||||
return &Knowledge{}
|
||||
}
|
||||
|
||||
type Knowledge struct {
|
||||
Id int32 `json:"id"` // TIP int64 会炸 ES 的 ‘integer’
|
||||
Dirs []string `json:"dirs"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
func (k *Knowledge) IndexName() string {
|
||||
return "catface_knowledges"
|
||||
}
|
||||
|
||||
func (k *Knowledge) InsertDocument() error {
|
||||
ctx := context.Background()
|
||||
|
||||
k.Id = int32(time.Now().UnixNano() / 1e6) // 将纳秒级时间戳转换为毫秒级 // INFO 自动补充时间戳为 ID
|
||||
|
||||
// 将结构体转换为 JSON 字符串
|
||||
data, err := json.Marshal(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建请求
|
||||
req := esapi.IndexRequest{
|
||||
Index: k.IndexName(),
|
||||
// DocumentID: fmt.Sprintf("%d", k.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 k map[string]interface{}
|
||||
if err := json.NewDecoder(res.Body).Decode(&k); err != nil {
|
||||
return fmt.Errorf("error parsing the response body: %s", err)
|
||||
} else {
|
||||
return fmt.Errorf("[%s] %s: %s",
|
||||
res.Status(),
|
||||
k["error"].(map[string]interface{})["type"],
|
||||
k["error"].(map[string]interface{})["reason"],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RandomDocuments 随机查询 num 个文档
|
||||
func (k *Knowledge) RandomDocuments(num int) ([]*Knowledge, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
// 创建本地随机数生成器 // TIP rand.Seed() 在 Go1.20 之后弃用了。
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
// 创建请求
|
||||
req := esapi.SearchRequest{
|
||||
Index: []string{k.IndexName()},
|
||||
Body: strings.NewReader(fmt.Sprintf(`{
|
||||
"size": %d,
|
||||
"query": {
|
||||
"function_score": {
|
||||
"query": { "match_all": {} },
|
||||
"random_score": {
|
||||
"seed": %d
|
||||
}
|
||||
}
|
||||
}
|
||||
}`, num, rng.Int63())),
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
res, err := req.Do(ctx, variable.ElasticClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.IsError() {
|
||||
var k map[string]interface{}
|
||||
if err := json.NewDecoder(res.Body).Decode(&k); err != nil {
|
||||
return nil, fmt.Errorf("error parsing the response body: %s", err)
|
||||
} else {
|
||||
return nil, fmt.Errorf("[%s] %s: %s",
|
||||
res.Status(),
|
||||
k["error"].(map[string]interface{})["type"],
|
||||
k["error"].(map[string]interface{})["reason"],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 解析响应
|
||||
var result map[string]interface{}
|
||||
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 提取文档
|
||||
hits := result["hits"].(map[string]interface{})["hits"].([]interface{})
|
||||
|
||||
documents := make([]*Knowledge, len(hits))
|
||||
for i, hit := range hits {
|
||||
source := hit.(map[string]interface{})["_source"].(map[string]interface{})
|
||||
|
||||
// 将 []interface{} 转换为 []string
|
||||
dirs := make([]string, len(source["dirs"].([]interface{})))
|
||||
for j, dir := range source["dirs"].([]interface{}) {
|
||||
dirs[j] = dir.(string)
|
||||
}
|
||||
|
||||
doc := &Knowledge{
|
||||
Dirs: dirs,
|
||||
Title: source["title"].(string),
|
||||
Content: source["content"].(string),
|
||||
}
|
||||
documents[i] = doc
|
||||
}
|
||||
|
||||
return documents, nil
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"catface/app/global/variable"
|
||||
"catface/app/model"
|
||||
"catface/app/model_es"
|
||||
_ "catface/bootstrap"
|
||||
@ -35,7 +34,7 @@ func TestEncounterEs(t *testing.T) {
|
||||
// }
|
||||
|
||||
// 查询文档
|
||||
encounters, err := encounter.QueryDocumentsMatchAll(variable.ElasticClient, "猪皮")
|
||||
encounters, err := encounter.QueryDocumentsMatchAll("猪皮")
|
||||
if err != nil {
|
||||
t.Fatalf("查询文档时出错: %s", err)
|
||||
}
|
||||
|
119
test/es/knowledge_test.go
Normal file
119
test/es/knowledge_test.go
Normal file
@ -0,0 +1,119 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"catface/app/model_es"
|
||||
_ "catface/bootstrap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var Know_vacc_1 = []model_es.Knowledge{
|
||||
{
|
||||
Dirs: []string{"疫苗", "喵三联"},
|
||||
Title: "概念",
|
||||
Content: "喵三联疫苗是一种针对猫咪的疫苗组合,通常包含三种疫苗,以提供对猫瘟、白血、传腹三种主要疾病的防护。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"疫苗", "喵三联"},
|
||||
Title: "接种周期",
|
||||
Content: "1. 幼猫:通常在6-8周大开始接种第一剂,之后每3-4周接种一次,直到完成基础免疫。\n2. 成猫:完成基础免疫后,每年进行一次加强接种。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"疫苗", "喵三联"},
|
||||
Title: "副作用",
|
||||
Content: "像所有疫苗一样,喵三联疫苗可能会有轻微的副作用,如注射部位的红肿、疼痛或轻微的发烧。",
|
||||
},
|
||||
}
|
||||
|
||||
var Know_food = []model_es.Knowledge{
|
||||
{
|
||||
Dirs: []string{"食物"},
|
||||
Title: "猫粮",
|
||||
Content: "选择专为猫设计的猫粮,考虑其年龄、体重、健康状况和活动水平,确保营养均衡,避免含有对猫有害的成分。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"食物"},
|
||||
Title: "猫条",
|
||||
Content: "猫条可作为零食或训练工具,选择高质量猫条,适量喂食,注意热量控制,避免肥胖。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"食物"},
|
||||
Title: "人类食物对猫的影响",
|
||||
Content: "人类食物可能不适合猫,某些食物对猫有毒,高盐、高糖或高脂肪食物可能导致健康问题,不应作为猫咪日常饮食。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"食物"},
|
||||
Title: "猫粮的营养成分",
|
||||
Content: "猫粮应包含高质量的蛋白质、脂肪、维生素和矿物质,以满足猫的营养需求。",
|
||||
},
|
||||
}
|
||||
|
||||
var Know_WHU = []model_es.Knowledge{
|
||||
{
|
||||
Dirs: []string{"WHU"},
|
||||
Title: "狂犬疫苗接种点",
|
||||
Content: "地质医院是离武大最近的接种点。",
|
||||
},
|
||||
}
|
||||
|
||||
var Know_viuse = []model_es.Knowledge{
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "概念",
|
||||
Content: "狂犬病毒是一种通过动物咬伤或唾液传播的病毒,主要影响中枢神经系统,对人类和动物都具有致命性。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "人类症状",
|
||||
Content: "人类感染狂犬病毒后,初期可能表现为发热、头痛、恶心等症状,随后可能出现恐惧、兴奋、幻觉、瘫痪和昏迷等严重症状。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "传播途径",
|
||||
Content: "狂犬病毒主要通过被感染动物的咬伤传播,也可能通过唾液直接接触眼睛、鼻子或口腔而传播。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "与猫",
|
||||
Content: "猫可以感染狂犬病毒,但通常不表现出明显症状,可能成为无症状携带者,传播风险相对较低。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "猫狗预防",
|
||||
Content: "定期给猫接种狂犬病疫苗,避免与野生动物接触,及时处理伤口,并在疑似暴露后采取隔离措施。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "人类预防",
|
||||
Content: "避免接触可能携带狂犬病毒的动物,被动物咬伤后立即清洗伤口并接种疫苗,了解并遵守当地狂犬病预防和动物管理的法律法规。",
|
||||
},
|
||||
{
|
||||
Dirs: []string{"狂犬病"},
|
||||
Title: "治疗方法",
|
||||
Content: "狂犬病目前没有特效治疗,治疗主要针对症状,因此预防措施至关重要。",
|
||||
},
|
||||
}
|
||||
|
||||
func TestKnowledgesES(t *testing.T) {
|
||||
// 定义需要插入的数据
|
||||
knowledges := append((append(append(Know_viuse, Know_food...), Know_WHU...)), Know_vacc_1...)
|
||||
|
||||
// 遍历并插入每个知识条目
|
||||
for _, knowledge := range knowledges {
|
||||
err := knowledge.InsertDocument()
|
||||
if err != nil {
|
||||
t.Fatalf("Error inserting document: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomSearch(t *testing.T) {
|
||||
knowledges, err := model_es.CreateKnowledgeESFactory().RandomDocuments(5)
|
||||
if err != nil {
|
||||
t.Fatalf("Error retrieving random documents: %v", err)
|
||||
}
|
||||
|
||||
t.Log("随机搜索结果:", len(knowledges))
|
||||
for _, knowledge := range knowledges {
|
||||
t.Log(knowledge)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user