daShangDao_kfzgw-info/es/es.go
2025-12-31 17:56:22 +08:00

1090 lines
30 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
/*
#include <stdlib.h>
*/
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() {
//}