package main /* #include */ import "C" import ( "context" "encoding/json" "fmt" "github.com/elastic/go-elasticsearch/v8" "github.com/elastic/go-elasticsearch/v8/esapi" "log" "strings" "unsafe" ) // ESClient 封装Elasticsearch客户端 type ESClient struct { client *elasticsearch.Client } // IndexInfo 索引信息结构 type IndexInfo struct { Name string `json:"index"` // 索引名称 Health string `json:"health"` // 健康状态 green:所有主分片和副本分片都正常 yellow:主分片正常,但部分副本分片不正常 red:有主分片不正常 Status string `json:"status"` // 索引状态 open:为打开(可用) UUID string `json:"uuid"` // 索引的唯一标识符 Pri string `json:"pri"` // 主分片数量 Rep string `json:"rep"` // 副本分片数量 DocsCount string `json:"docs.count"` // 文档总数 DocsDeleted string `json:"docs.deleted"` // 已删除文档数 StoreSize string `json:"store.size"` // 总存储大小 PriStoreSize string `json:"pri.store.size"` // 主分片存储大小 Settings map[string]interface{} `json:"settings,omitempty"` // 索引设置 Mappings map[string]interface{} `json:"mappings,omitempty"` // 索引映射 Aliases []string `json:"aliases,omitempty"` // 索引别名 } // ES配置常量 const ( esAddress = "http://103.236.91.138:9200" // ES地址 esUsername = "elastic" // 用户名(如果有认证) esPassword = "5mRDIUg52VC0fp14nw-F" // 密码(如果有认证) ) // newESClient 创建ES客户端 func newESClient(addresses []string, username, password string) (*ESClient, error) { cfg := elasticsearch.Config{ Addresses: addresses, // ES节点地址 Username: username, // 用户名(如果有认证) Password: password, // 密码(如果有认证) } // 创建新的Elasticsearch客户端 client, err := elasticsearch.NewClient(cfg) if err != nil { return nil, fmt.Errorf("创建ES客户端失败: %w", err) } // 测试连接:发送ping请求验证连接是否正常 res, err := client.Ping() if err != nil { return nil, fmt.Errorf("连接ES失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { return nil, fmt.Errorf("ES响应错误: %s", res.String()) } log.Println("✅ 成功连接到Elasticsearch") return &ESClient{ client: client, // 返回封装的客户端 }, nil } // 查询所有索引 func (es *ESClient) listAllIndices() ([]string, error) { // 创建索引列表请求 req := esapi.CatIndicesRequest{ Format: "json", // 返回JSON格式 Pretty: true, // 美化输出 } // 执行请求 res, err := req.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("查询索引列表失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { return nil, fmt.Errorf("查询索引列表失败: %s", res.String()) } // 解析返回的索引信息 var indices []map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&indices); err != nil { return nil, fmt.Errorf("解析索引列表失败: %w", err) } // 提取索引名称 var indexNames []string for _, idx := range indices { if name, ok := idx["index"].(string); ok && name != "" { indexNames = append(indexNames, name) } } return indexNames, nil } // 获取所有索引的详细信息 func (es *ESClient) getIndicesInfo() ([]IndexInfo, error) { // 先获取所有索引名 indexNames, err := es.listAllIndices() if err != nil { return nil, err } // 如果有索引,获取详细信息 if len(indexNames) == 0 { return []IndexInfo{}, nil } // 获取索引的统计信息 statsReq := esapi.IndicesStatsRequest{ Index: indexNames, // 指定要查询的索引 Human: true, // 返回人类可读的格式 } statsRes, err := statsReq.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("获取索引统计信息失败: %w", err) } defer statsRes.Body.Close() // 确保响应体被关闭 if statsRes.IsError() { return nil, fmt.Errorf("获取索引统计信息失败: %s", statsRes.String()) } var statsResult map[string]interface{} if err := json.NewDecoder(statsRes.Body).Decode(&statsResult); err != nil { return nil, fmt.Errorf("解析索引统计信息失败: %w", err) } // 获取索引的健康状态 healthReq := esapi.CatIndicesRequest{ Index: indexNames, // 指定要查询的索引 Format: "json", // 返回JSON格式 H: []string{"index,health,status,pri,rep,docs.count,docs.deleted,store.size,pri.store.size"}, // 要返回的字段 } healthRes, err := healthReq.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("获取索引健康状态失败: %w", err) } defer healthRes.Body.Close() // 确保响应体被关闭 if healthRes.IsError() { return nil, fmt.Errorf("获取索引健康状态失败: %s", healthRes.String()) } var healthInfo []map[string]interface{} if err := json.NewDecoder(healthRes.Body).Decode(&healthInfo); err != nil { return nil, fmt.Errorf("解析索引健康状态失败: %w", err) } // 组合索引信息 var indicesInfo []IndexInfo for _, health := range healthInfo { indexName, _ := health["index"].(string) if indexName == "" { continue // 跳过空索引名 } // 构建索引信息结构 info := IndexInfo{ Name: indexName, Health: getString(health, "health", "unknown"), Status: getString(health, "status", "unknown"), Pri: getString(health, "pri", "0"), Rep: getString(health, "rep", "0"), DocsCount: getString(health, "docs.count", "0"), DocsDeleted: getString(health, "docs.deleted", "0"), StoreSize: getString(health, "store.size", "0b"), PriStoreSize: getString(health, "pri.store.size", "0b"), } indicesInfo = append(indicesInfo, info) } return indicesInfo, nil } // 获取单个索引的详细信息 func (es *ESClient) getIndexDetail(indexName string) (map[string]interface{}, error) { req := esapi.IndicesGetRequest{ Index: []string{indexName}, // 指定要查询的索引 } res, err := req.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("获取索引详情失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return nil, fmt.Errorf("索引不存在: %s", indexName) } return nil, fmt.Errorf("获取索引详情失败: %s", res.String()) } var result map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&result); err != nil { return nil, fmt.Errorf("解析索引详情失败: %w", err) } return result, nil } // 获取索引设置 func (es *ESClient) getIndexSettings(indexName string) (map[string]interface{}, error) { req := esapi.IndicesGetSettingsRequest{ Index: []string{indexName}, // 指定要查询的索引 } res, err := req.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("获取索引设置失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return nil, fmt.Errorf("索引不存在: %s", indexName) } return nil, fmt.Errorf("获取索引设置失败: %s", res.String()) } var result map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&result); err != nil { return nil, fmt.Errorf("解析索引设置失败: %w", err) } return result, nil } // createIndex 创建索引(如果不存在) func (es *ESClient) createIndex(indexName string, mapping string) (map[string]interface{}, error) { // 检查索引是否存在 res, err := es.client.Indices.Exists([]string{indexName}) if err != nil { return nil, fmt.Errorf("检查索引存在失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 如果索引已存在,直接返回 if res.StatusCode == 200 { log.Printf("索引 %s 已存在\n", indexName) detail, err := es.getIndexDetail(indexName) if err != nil { return nil, err } return detail, nil } // 创建索引请求 req := esapi.IndicesCreateRequest{ Index: indexName, // 索引名称 Body: strings.NewReader(mapping), // 索引映射配置 } // 执行创建索引请求 res, err = req.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("创建索引请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { return nil, fmt.Errorf("创建索引失败: %s", res.String()) } // 获取新创建索引的详情 detail, err := es.getIndexDetail(indexName) if err != nil { return nil, err } log.Printf("✅ 成功创建索引: %s\n", indexName) return detail, nil } // deleteIndex 删除索引 func (es *ESClient) deleteIndex(indexName string) error { req := esapi.IndicesDeleteRequest{ Index: []string{indexName}, // 要删除的索引 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("删除索引请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("索引不存在: %s", indexName) } return fmt.Errorf("删除索引失败: %s", res.String()) } log.Printf("✅ 成功删除索引: %s\n", indexName) return nil } // 更新索引设置 func (es *ESClient) updateIndexSettings(indexName string, settings map[string]interface{}) error { // 构建设置请求体 requestBody := map[string]interface{}{ "settings": settings, // 新的设置参数 } bodyJSON, err := json.Marshal(requestBody) if err != nil { return fmt.Errorf("序列化设置失败: %w", err) } req := esapi.IndicesPutSettingsRequest{ Index: []string{indexName}, // 要更新的索引 Body: strings.NewReader(string(bodyJSON)), // 设置内容 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("更新索引设置请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("索引不存在: %s", indexName) } return fmt.Errorf("更新索引设置失败: %s", res.String()) } log.Printf("✅ 成功更新索引设置: %s\n", indexName) return nil } // 更新索引映射(添加新字段) func (es *ESClient) updateIndexMappings(indexName string, newMappings map[string]interface{}) error { // 构建映射请求体 requestBody := map[string]interface{}{ "properties": newMappings, // 新的映射字段 } bodyJSON, err := json.Marshal(requestBody) if err != nil { return fmt.Errorf("序列化映射失败: %w", err) } req := esapi.IndicesPutMappingRequest{ Index: []string{indexName}, // 要更新的索引 Body: strings.NewReader(string(bodyJSON)), // 映射内容 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("更新索引映射请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("索引不存在: %s", indexName) } return fmt.Errorf("更新索引映射失败: %s", res.String()) } log.Printf("✅ 成功更新索引映射: %s\n", indexName) return nil } // 关闭索引 func (es *ESClient) closeIndex(indexName string) error { req := esapi.IndicesCloseRequest{ Index: []string{indexName}, // 要关闭的索引 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("关闭索引请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("索引不存在: %s", indexName) } return fmt.Errorf("关闭索引失败: %s", res.String()) } log.Printf("✅ 已关闭索引: %s\n", indexName) return nil } // 打开索引 func (es *ESClient) openIndex(indexName string) error { req := esapi.IndicesOpenRequest{ Index: []string{indexName}, // 要打开的索引 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("打开索引请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("索引不存在: %s", indexName) } return fmt.Errorf("打开索引失败: %s", res.String()) } log.Printf("✅ 已打开索引: %s\n", indexName) return nil } // getDocumentCount 获取索引文档数量 func (es *ESClient) getDocumentCount(indexName string) (int64, error) { req := esapi.CountRequest{ Index: []string{indexName}, // 要计数的索引 } res, err := req.Do(context.Background(), es.client) if err != nil { return 0, fmt.Errorf("获取文档数量请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 if res.IsError() { if res.StatusCode == 404 { return 0, fmt.Errorf("索引不存在: %s", indexName) } return 0, fmt.Errorf("获取文档数量失败: %s", res.String()) } var result map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&result); err != nil { return 0, fmt.Errorf("解析响应失败: %w", err) } // 提取文档数量 if count, ok := result["count"].(float64); ok { return int64(count), nil } return 0, fmt.Errorf("无法获取文档数量") } // ========================== 文档相关操作 ============= // createDocument 创建文档 func (es *ESClient) createDocument(indexName string, id string, doc interface{}) error { // 将文档序列化为JSON docJSON, err := json.Marshal(doc) if err != nil { return fmt.Errorf("序列化文档失败: %w", err) } req := esapi.IndexRequest{ Index: indexName, // 目标索引 DocumentID: id, // 文档ID(可选,为空时ES自动生成) Body: strings.NewReader(string(docJSON)), // 文档内容 Refresh: "true", // 立即刷新使文档可搜索 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("创建文档请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { return fmt.Errorf("创建文档失败: %s", res.String()) } log.Printf("✅ 成功创建文档: indexName=%s\n", indexName) return nil } // getDocument 根据ID获取文档 func (es *ESClient) getDocument(indexName string, id string) (map[string]interface{}, error) { req := esapi.GetRequest{ Index: indexName, // 索引名称 DocumentID: id, // 文档ID } res, err := req.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("获取文档请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return nil, fmt.Errorf("文档不存在: ID=%s", id) } return nil, fmt.Errorf("获取文档失败: %s", res.String()) } var result map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&result); err != nil { return nil, fmt.Errorf("解析响应失败: %w", err) } return result, nil } // updateDocument 更新文档 func (es *ESClient) updateDocument(indexName string, id string, updateData map[string]interface{}) error { // 构建更新脚本 updateBody := map[string]interface{}{ "doc": updateData, // 更新内容放在doc字段中 } bodyJSON, err := json.Marshal(updateBody) if err != nil { return fmt.Errorf("序列化更新数据失败: %w", err) } req := esapi.UpdateRequest{ Index: indexName, // 索引名称 DocumentID: id, // 文档ID Body: strings.NewReader(string(bodyJSON)), // 更新内容 Refresh: "true", // 立即刷新使更新可搜索 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("更新文档请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("文档不存在: ID=%s", id) } return fmt.Errorf("更新文档失败: %s", res.String()) } log.Printf("✅ 成功更新文档: ID=%s\n", id) return nil } // deleteDocument 删除文档 func (es *ESClient) deleteDocument(indexName string, id string) error { req := esapi.DeleteRequest{ Index: indexName, // 索引名称 DocumentID: id, // 文档ID Refresh: "true", // 立即刷新 } res, err := req.Do(context.Background(), es.client) if err != nil { return fmt.Errorf("删除文档请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { if res.StatusCode == 404 { return fmt.Errorf("文档不存在: ID=%s", id) } return fmt.Errorf("删除文档失败: %s", res.String()) } log.Printf("✅ 成功删除文档: ID=%s\n", id) return nil } // searchDocuments 搜索文档 func (es *ESClient) searchDocuments(indexName string, query map[string]interface{}) ([]map[string]interface{}, error) { // 将查询条件序列化为JSON queryJSON, err := json.Marshal(query) if err != nil { return nil, fmt.Errorf("序列化查询失败: %w", err) } req := esapi.SearchRequest{ Index: []string{indexName}, // 要搜索的索引 Body: strings.NewReader(string(queryJSON)), // 查询条件 } res, err := req.Do(context.Background(), es.client) if err != nil { return nil, fmt.Errorf("搜索请求失败: %w", err) } defer res.Body.Close() // 确保响应体被关闭 // 检查响应状态 if res.IsError() { return nil, fmt.Errorf("搜索失败: %s", res.String()) } var result map[string]interface{} if err := json.NewDecoder(res.Body).Decode(&result); err != nil { return nil, fmt.Errorf("解析搜索结果失败: %w", err) } // 提取命中的文档 hits, ok := result["hits"].(map[string]interface{}) if !ok { return []map[string]interface{}{}, nil // 没有命中结果 } hitsArray, ok := hits["hits"].([]interface{}) if !ok { return []map[string]interface{}{}, nil // 命中结果格式不正确 } // 处理每个命中文档 var documents []map[string]interface{} for _, hit := range hitsArray { if hitMap, ok := hit.(map[string]interface{}); ok { if source, ok := hitMap["_source"].(map[string]interface{}); ok { source["_id"] = hitMap["_id"] // 将文档ID添加到结果中 documents = append(documents, source) } } } return documents, nil } //// BulkCreate 批量创建文档 //func (es *ESClient) BulkCreate(docs map[string]interface{}) error { // var body string // for id, doc := range docs { // docJSON, err := json.Marshal(doc) // if err != nil { // return fmt.Errorf("序列化文档失败: %w", err) // } // // // 批量操作格式 // body += fmt.Sprintf(`{"index":{"_index":"%s","_id":"%s"}}%s`, es.index, id, "\n") // body += string(docJSON) + "\n" // } // // req := esapi.BulkRequest{ // Body: strings.NewReader(body), // } // // res, err := req.Do(context.Background(), es.client) // if err != nil { // return fmt.Errorf("批量操作请求失败: %w", err) // } // defer res.Body.Close() // // if res.IsError() { // return fmt.Errorf("批量操作失败: %s", res.String()) // } // // log.Printf("✅ 批量创建 %d 个文档成功\n", len(docs)) // return nil //} // ==================== 辅助函数 ==================== // getString 从map中安全获取字符串值,避免类型断言失败 func getString(m map[string]interface{}, key, defaultValue string) string { if val, ok := m[key]; ok { if str, ok := val.(string); ok { return str } } return defaultValue // 如果key不存在或不是字符串类型,返回默认值 } // =================== C 导入函数 ======================= // c响应信息 type APIResponse struct { Success bool `json:"success"` // 操作是否成功 Message string `json:"message"` // 响应消息(错误时为错误信息) Data interface{} `json:"data"` // 响应数据(成功时返回) } // ListAllIndices 查询所有索引 // //export ListAllIndices func ListAllIndices() *C.char { var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // 查询所有索引 info, err := client.listAllIndices() if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // GetIndicesInfo 获取所有索引的详细信息 // //export GetIndicesInfo func GetIndicesInfo() *C.char { var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // 获取所有索引的详细信息 info, err := client.getIndicesInfo() if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // GetIndexDetail 获取单个索引的详细信息 // //export GetIndexDetail func GetIndexDetail(indexName *C.char) *C.char { goIndexName := C.GoString(indexName) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } info, err := client.getIndexDetail(goIndexName) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // CreateIndex 创建索引(如果不存在) // //export CreateIndex func CreateIndex(indexName, mapping *C.char) *C.char { goIndexName := C.GoString(indexName) goMapping := C.GoString(mapping) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } info, err := client.createIndex(goIndexName, goMapping) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // DeleteIndex 删除索引 // //export DeleteIndex func DeleteIndex(indexName *C.char) *C.char { goIndexName := C.GoString(indexName) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } err = client.deleteIndex(goIndexName) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // GetDocumentCount 获取索引文档数量 // //export GetDocumentCount func GetDocumentCount(indexName *C.char) *C.char { goIndexName := C.GoString(indexName) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } info, err := client.getDocumentCount(goIndexName) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // CreateDocument 创建文档 // //export CreateDocument func CreateDocument(indexName *C.char, id *C.char, doc *C.char) *C.char { goIndexName := C.GoString(indexName) goId := C.GoString(id) goDoc := C.GoString(doc) var apiResp APIResponse var newDoc interface{} if err := json.Unmarshal([]byte(goDoc), &newDoc); err != nil { apiResp = APIResponse{ Success: false, Message: fmt.Sprintf("解析JSON失败: %v", err), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } err = client.createDocument(goIndexName, goId, newDoc) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // GetDocument 根据ID获取文档 // //export GetDocument func GetDocument(indexName *C.char, id *C.char) *C.char { goIndexName := C.GoString(indexName) goId := C.GoString(id) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } info, err := client.getDocument(goIndexName, goId) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // UpdateDocument 更新文档 // //export UpdateDocument func UpdateDocument(indexName *C.char, id *C.char, updateData *C.char) *C.char { goIndexName := C.GoString(indexName) goId := C.GoString(id) goUpdateData := C.GoString(updateData) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // 转换updateData var newUpdateData map[string]interface{} if err = json.Unmarshal([]byte(goUpdateData), &newUpdateData); err != nil { apiResp = APIResponse{ Success: false, Message: fmt.Sprintf("解析JSON失败: %v", err), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } err = client.updateDocument(goIndexName, goId, newUpdateData) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // DeleteDocument 删除文档 // //export DeleteDocument func DeleteDocument(indexName *C.char, id *C.char) *C.char { goIndexName := C.GoString(indexName) goId := C.GoString(id) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } err = client.deleteDocument(goIndexName, goId) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // SearchDocuments 搜索文档 // //export SearchDocuments func SearchDocuments(indexName *C.char, query *C.char) *C.char { goIndexName := C.GoString(indexName) goQuery := C.GoString(query) var apiResp APIResponse // 创建ES客户端 client, err := newESClient([]string{esAddress}, esUsername, esPassword) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // 转换updateData 解析json var newQuery map[string]interface{} if err = json.Unmarshal([]byte(goQuery), &newQuery); err != nil { apiResp = APIResponse{ Success: false, Message: fmt.Sprintf("解析JSON失败: %v", err), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } info, err := client.searchDocuments(goIndexName, newQuery) if err != nil { apiResp = APIResponse{ Success: false, Message: err.Error(), } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } apiResp = APIResponse{ Success: true, Data: info, } apiRespStr, _ := json.Marshal(apiResp) return C.CString(string(apiRespStr)) } // 释放C字符串内存 // //export FreeCString func FreeCString(str *C.char) { C.free(unsafe.Pointer(str)) } // main 函数 //func main() { //}