Browse Source

根据问题匹配答案

renjiaojiao 3 years ago
parent
commit
66b79dd005

+ 4 - 2
entity/db.go

@@ -26,6 +26,8 @@ type RedisStruct struct {
 
 // EsStruct es
 type EsStruct struct {
-	Addr string `json:"addr"`
-	Size int    `json:"size"`
+	Addr  string `json:"addr"`
+	Size  int    `json:"size"`
+	Index string `json:"index"`
+	Type  string `json:"type"`
 }

+ 4 - 1
rpc/knowledge/etc/knowledge.yaml

@@ -2,7 +2,7 @@ Name: knowledge.rpc
 ListenOn: 127.0.0.1:8080
 Etcd:
   Hosts:
-  - 192.168.3.240:2379
+    - 192.168.3.240:2379
   Key: knowledge.rpc
 WebRpcPort: 8014
 MysqlMain:
@@ -15,3 +15,6 @@ MysqlMain:
 Es:
   addr: http://192.168.3.206:9800
   size: 5
+  index: smart
+  type: smart
+Segment: http://192.168.3.204:8080/api/segment

+ 1 - 0
rpc/knowledge/internal/config/config.go

@@ -10,4 +10,5 @@ type Config struct {
 	WebRpcPort int64
 	MysqlMain  entity.MysqlMainStruct
 	Es         entity.EsStruct
+	Segment    string
 }

+ 50 - 0
rpc/knowledge/internal/logic/findanswerlogic.go

@@ -0,0 +1,50 @@
+package logic
+
+import (
+	cm "app.yhyue.com/moapp/jybase/common"
+	elastic "app.yhyue.com/moapp/jybase/esv1"
+	"context"
+	"fmt"
+	"github.com/zeromicro/go-zero/core/logx"
+	. "knowledgeBase/rpc/knowledge/init"
+	"knowledgeBase/rpc/knowledge/knowledgeclient"
+	"knowledgeBase/rpc/knowledge/utils"
+	"strconv"
+
+	"knowledgeBase/rpc/knowledge/internal/svc"
+)
+
+type FindAnswerLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewFindAnswerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FindAnswerLogic {
+	return &FindAnswerLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *FindAnswerLogic) FindAnswer(in *knowledgeclient.FindAnswerReq) (*knowledgeclient.FindAnswerResp, error) {
+	// todo: add your logic here and delete this line
+	var question *knowledgeclient.Question
+	tenantId := strconv.Itoa(int(in.TenantId))
+	query := utils.DSL4SmartResponse(in.Question, tenantId, int(in.Type))
+	fmt.Println("query:", query)
+	res := elastic.Get(C.Es.Index, C.Es.Type, query)
+	if res != nil && len(*res) > 0 {
+		data := (*res)[0]
+		question.XId = cm.ObjToString(data["_id"])
+		question.Answer = cm.ObjToString(data["answer"])
+		question.Question = cm.ObjToString(data["question"])
+	}
+	fmt.Println("根据问题匹配答案:", question)
+	return &knowledgeclient.FindAnswerResp{
+		ErrorCode: 1,
+		ErrorMsg:  "请求成功",
+		Data:      question,
+	}, nil
+}

+ 76 - 0
rpc/knowledge/internal/logic/recommendanswerlogic.go

@@ -0,0 +1,76 @@
+package logic
+
+import (
+	"context"
+	"github.com/zeromicro/go-zero/core/logx"
+	"knowledgeBase/rpc/knowledge/internal/svc"
+	"knowledgeBase/rpc/knowledge/knowledgeclient"
+)
+
+type RecommendAnswerLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewRecommendAnswerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RecommendAnswerLogic {
+	return &RecommendAnswerLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *RecommendAnswerLogic) RecommendAnswer(in *knowledgeclient.FindAnswerReq) (*knowledgeclient.RecommendAnswerResp, error) {
+	// todo: add your logic here and delete this line
+
+	/*question := in.Question
+	result := utils.HttpDo(in.Question)
+	var resmap []map[string]interface{}
+	json.Unmarshal([]byte(result), &resmap)
+
+	pid := utils.BsonIdToSId(res["pid"])
+	//log.Println(pid)
+	rquery := map[string]interface{}{
+		"platFormUserId": pid,
+	}
+	repository := repositoryService.FindByField(rquery)
+	repositoryId := utils.BsonIdToSId(repository.Id)
+
+	repositoryIdArr := getCiteRepository(pid)
+	var strr string
+	if len(repositoryIdArr) > 0 {
+		strr = "," + "\"" + repositoryId + "\""
+	} else {
+		strr = "\"" + repositoryId + "\""
+	}
+	repositoryIdArr = append(repositoryIdArr, strr)
+
+	var kws = ""
+	var link_obj = &[]map[string]interface{}{}
+	if len(resmap) > 0 {
+		for k, v := range resmap {
+			if strings.Contains(v["nature"].(string), "n") && len(v["word"].(string)) > 3 {
+				if k > 0 && len(kws) > 1 {
+					kws += " "
+				}
+				kws += v["word"].(string)
+			}
+		}
+	}
+	//fmt.Println("关键字:", kws)
+	var search_field = `"_id","knowledgeKeyWords","answer","relativeKnowledgeId","createUser","tags","questions","repositoryId","createTime","updateTime","must_keywords","highweight_keywords"`
+	if kws != "" {
+		var qstr = tools.DSL4SearchByKwsOrid(kws, id, repositoryIdArr)
+		link_obj = elastic.GetAllByNgram(INDEX, TYPE, qstr, "", "", search_field, 0, 5, 0, false)
+		//log.Println("link_obj:", link_obj)
+	} else {
+
+	}
+	obj := []interface{}{}
+	obj = append(obj, kws)
+	obj = append(obj, link_obj)
+	context.JSON(http.StatusOK, obj)*/
+
+	return &knowledgeclient.RecommendAnswerResp{}, nil
+}

+ 10 - 0
rpc/knowledge/internal/server/knowledgeserver.go

@@ -25,3 +25,13 @@ func (s *KnowledgeServer) Knowledge(ctx context.Context, in *knowledgeclient.Add
 	l := logic.NewKnowledgeLogic(ctx, s.svcCtx)
 	return l.Knowledge(in)
 }
+
+func (s *KnowledgeServer) FindAnswer(ctx context.Context, in *knowledgeclient.FindAnswerReq) (*knowledgeclient.FindAnswerResp, error) {
+	l := logic.NewFindAnswerLogic(ctx, s.svcCtx)
+	return l.FindAnswer(in)
+}
+
+func (s *KnowledgeServer) RecommendAnswer(ctx context.Context, in *knowledgeclient.FindAnswerReq) (*knowledgeclient.RecommendAnswerResp, error) {
+	l := logic.NewRecommendAnswerLogic(ctx, s.svcCtx)
+	return l.RecommendAnswer(in)
+}

+ 27 - 0
rpc/knowledge/knowledge.proto

@@ -4,6 +4,12 @@ package template;
 
 option go_package = "./knowledge";
 
+message Question {
+  string _id = 1;
+  string question = 2;
+  string answer = 3;
+}
+
 message AddRequest {
   string question = 1;
   string answer = 2;
@@ -15,6 +21,27 @@ message AddResponse{
   string data = 3; //响应内容
 }
 
+message FindAnswerReq{
+  string question = 1;
+  int64 tenantId = 2;//租户id
+  int64 type = 3;// 1文字  2语音
+  string appId = 4;
+}
+
+message FindAnswerResp{
+  int64 error_code = 1; //响应代码
+  string error_msg = 2; //响应消息
+  Question data = 3; //响应内容
+}
+
+message RecommendAnswerResp{
+  int64 error_code = 1; //响应代码
+  string error_msg = 2; //响应消息
+  repeated Question data = 3; //响应内容
+}
+
 service knowledge {
   rpc knowledge(AddRequest) returns(AddResponse);
+  rpc FindAnswer(FindAnswerReq) returns(FindAnswerResp);
+  rpc RecommendAnswer(FindAnswerReq) returns(RecommendAnswerResp);
 }

+ 461 - 35
rpc/knowledge/knowledge/knowledge.pb.go

@@ -24,6 +24,69 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
+type Question struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	XId      string `protobuf:"bytes,1,opt,name=_id,json=Id,proto3" json:"_id,omitempty"`
+	Question string `protobuf:"bytes,2,opt,name=question,proto3" json:"question,omitempty"`
+	Answer   string `protobuf:"bytes,3,opt,name=answer,proto3" json:"answer,omitempty"`
+}
+
+func (x *Question) Reset() {
+	*x = Question{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_knowledge_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Question) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Question) ProtoMessage() {}
+
+func (x *Question) ProtoReflect() protoreflect.Message {
+	mi := &file_knowledge_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Question.ProtoReflect.Descriptor instead.
+func (*Question) Descriptor() ([]byte, []int) {
+	return file_knowledge_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Question) GetXId() string {
+	if x != nil {
+		return x.XId
+	}
+	return ""
+}
+
+func (x *Question) GetQuestion() string {
+	if x != nil {
+		return x.Question
+	}
+	return ""
+}
+
+func (x *Question) GetAnswer() string {
+	if x != nil {
+		return x.Answer
+	}
+	return ""
+}
+
 type AddRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -36,7 +99,7 @@ type AddRequest struct {
 func (x *AddRequest) Reset() {
 	*x = AddRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_knowledge_proto_msgTypes[0]
+		mi := &file_knowledge_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -49,7 +112,7 @@ func (x *AddRequest) String() string {
 func (*AddRequest) ProtoMessage() {}
 
 func (x *AddRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_knowledge_proto_msgTypes[0]
+	mi := &file_knowledge_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -62,7 +125,7 @@ func (x *AddRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AddRequest.ProtoReflect.Descriptor instead.
 func (*AddRequest) Descriptor() ([]byte, []int) {
-	return file_knowledge_proto_rawDescGZIP(), []int{0}
+	return file_knowledge_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *AddRequest) GetQuestion() string {
@@ -92,7 +155,7 @@ type AddResponse struct {
 func (x *AddResponse) Reset() {
 	*x = AddResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_knowledge_proto_msgTypes[1]
+		mi := &file_knowledge_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -105,7 +168,7 @@ func (x *AddResponse) String() string {
 func (*AddResponse) ProtoMessage() {}
 
 func (x *AddResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_knowledge_proto_msgTypes[1]
+	mi := &file_knowledge_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -118,7 +181,7 @@ func (x *AddResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AddResponse.ProtoReflect.Descriptor instead.
 func (*AddResponse) Descriptor() ([]byte, []int) {
-	return file_knowledge_proto_rawDescGZIP(), []int{1}
+	return file_knowledge_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *AddResponse) GetErrorCode() int64 {
@@ -142,27 +205,260 @@ func (x *AddResponse) GetData() string {
 	return ""
 }
 
+type FindAnswerReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Question string `protobuf:"bytes,1,opt,name=question,proto3" json:"question,omitempty"`
+	TenantId int64  `protobuf:"varint,2,opt,name=tenantId,proto3" json:"tenantId,omitempty"` //租户id
+	Type     int64  `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"`         // 1文字  2语音
+	AppId    string `protobuf:"bytes,4,opt,name=appId,proto3" json:"appId,omitempty"`
+}
+
+func (x *FindAnswerReq) Reset() {
+	*x = FindAnswerReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_knowledge_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindAnswerReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindAnswerReq) ProtoMessage() {}
+
+func (x *FindAnswerReq) ProtoReflect() protoreflect.Message {
+	mi := &file_knowledge_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindAnswerReq.ProtoReflect.Descriptor instead.
+func (*FindAnswerReq) Descriptor() ([]byte, []int) {
+	return file_knowledge_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *FindAnswerReq) GetQuestion() string {
+	if x != nil {
+		return x.Question
+	}
+	return ""
+}
+
+func (x *FindAnswerReq) GetTenantId() int64 {
+	if x != nil {
+		return x.TenantId
+	}
+	return 0
+}
+
+func (x *FindAnswerReq) GetType() int64 {
+	if x != nil {
+		return x.Type
+	}
+	return 0
+}
+
+func (x *FindAnswerReq) GetAppId() string {
+	if x != nil {
+		return x.AppId
+	}
+	return ""
+}
+
+type FindAnswerResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ErrorCode int64     `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` //响应代码
+	ErrorMsg  string    `protobuf:"bytes,2,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"`     //响应消息
+	Data      *Question `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`                             //响应内容
+}
+
+func (x *FindAnswerResp) Reset() {
+	*x = FindAnswerResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_knowledge_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FindAnswerResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindAnswerResp) ProtoMessage() {}
+
+func (x *FindAnswerResp) ProtoReflect() protoreflect.Message {
+	mi := &file_knowledge_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindAnswerResp.ProtoReflect.Descriptor instead.
+func (*FindAnswerResp) Descriptor() ([]byte, []int) {
+	return file_knowledge_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *FindAnswerResp) GetErrorCode() int64 {
+	if x != nil {
+		return x.ErrorCode
+	}
+	return 0
+}
+
+func (x *FindAnswerResp) GetErrorMsg() string {
+	if x != nil {
+		return x.ErrorMsg
+	}
+	return ""
+}
+
+func (x *FindAnswerResp) GetData() *Question {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type RecommendAnswerResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ErrorCode int64       `protobuf:"varint,1,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` //响应代码
+	ErrorMsg  string      `protobuf:"bytes,2,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"`     //响应消息
+	Data      []*Question `protobuf:"bytes,3,rep,name=data,proto3" json:"data,omitempty"`                             //响应内容
+}
+
+func (x *RecommendAnswerResp) Reset() {
+	*x = RecommendAnswerResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_knowledge_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RecommendAnswerResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RecommendAnswerResp) ProtoMessage() {}
+
+func (x *RecommendAnswerResp) ProtoReflect() protoreflect.Message {
+	mi := &file_knowledge_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RecommendAnswerResp.ProtoReflect.Descriptor instead.
+func (*RecommendAnswerResp) Descriptor() ([]byte, []int) {
+	return file_knowledge_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *RecommendAnswerResp) GetErrorCode() int64 {
+	if x != nil {
+		return x.ErrorCode
+	}
+	return 0
+}
+
+func (x *RecommendAnswerResp) GetErrorMsg() string {
+	if x != nil {
+		return x.ErrorMsg
+	}
+	return ""
+}
+
+func (x *RecommendAnswerResp) GetData() []*Question {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
 var File_knowledge_proto protoreflect.FileDescriptor
 
 var file_knowledge_proto_rawDesc = []byte{
 	0x0a, 0x0f, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x12, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x40, 0x0a, 0x0a, 0x41,
-	0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x22, 0x5d, 0x0a,
-	0x0b, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
-	0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
-	0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65,
-	0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
-	0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x45, 0x0a, 0x09,
-	0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x6b, 0x6e, 0x6f,
-	0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x12, 0x14, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
-	0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x74,
-	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64,
-	0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x6f, 0x12, 0x08, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x4f, 0x0a, 0x08, 0x51,
+	0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x22, 0x40, 0x0a, 0x0a,
+	0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x22, 0x5d,
+	0x0a, 0x0b, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a,
+	0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09,
+	0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74,
+	0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x71, 0x0a,
+	0x0d, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1a,
+	0x0a, 0x08, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65,
+	0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x74, 0x65,
+	0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70,
+	0x70, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64,
+	0x22, 0x74, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x52, 0x65,
+	0x73, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64,
+	0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x26,
+	0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x79, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d,
+	0x65, 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1d, 0x0a,
+	0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09,
+	0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74,
+	0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+	0x74, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x64, 0x61, 0x74,
+	0x61, 0x32, 0xd1, 0x01, 0x0a, 0x09, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x12,
+	0x38, 0x0a, 0x09, 0x6b, 0x6e, 0x6f, 0x77, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x12, 0x14, 0x2e, 0x74,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x15, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x64,
+	0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x46, 0x69, 0x6e,
+	0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+	0x74, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x52, 0x65, 0x71,
+	0x1a, 0x18, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64,
+	0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x49, 0x0a, 0x0f, 0x52, 0x65,
+	0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x12, 0x17, 0x2e,
+	0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6e, 0x73,
+	0x77, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
+	0x65, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x73, 0x77, 0x65,
+	0x72, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x6b, 0x6e, 0x6f, 0x77, 0x6c,
+	0x65, 0x64, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -177,19 +473,29 @@ func file_knowledge_proto_rawDescGZIP() []byte {
 	return file_knowledge_proto_rawDescData
 }
 
-var file_knowledge_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_knowledge_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
 var file_knowledge_proto_goTypes = []interface{}{
-	(*AddRequest)(nil),  // 0: template.AddRequest
-	(*AddResponse)(nil), // 1: template.AddResponse
+	(*Question)(nil),            // 0: template.Question
+	(*AddRequest)(nil),          // 1: template.AddRequest
+	(*AddResponse)(nil),         // 2: template.AddResponse
+	(*FindAnswerReq)(nil),       // 3: template.FindAnswerReq
+	(*FindAnswerResp)(nil),      // 4: template.FindAnswerResp
+	(*RecommendAnswerResp)(nil), // 5: template.RecommendAnswerResp
 }
 var file_knowledge_proto_depIdxs = []int32{
-	0, // 0: template.knowledge.knowledge:input_type -> template.AddRequest
-	1, // 1: template.knowledge.knowledge:output_type -> template.AddResponse
-	1, // [1:2] is the sub-list for method output_type
-	0, // [0:1] is the sub-list for method input_type
-	0, // [0:0] is the sub-list for extension type_name
-	0, // [0:0] is the sub-list for extension extendee
-	0, // [0:0] is the sub-list for field type_name
+	0, // 0: template.FindAnswerResp.data:type_name -> template.Question
+	0, // 1: template.RecommendAnswerResp.data:type_name -> template.Question
+	1, // 2: template.knowledge.knowledge:input_type -> template.AddRequest
+	3, // 3: template.knowledge.FindAnswer:input_type -> template.FindAnswerReq
+	3, // 4: template.knowledge.RecommendAnswer:input_type -> template.FindAnswerReq
+	2, // 5: template.knowledge.knowledge:output_type -> template.AddResponse
+	4, // 6: template.knowledge.FindAnswer:output_type -> template.FindAnswerResp
+	5, // 7: template.knowledge.RecommendAnswer:output_type -> template.RecommendAnswerResp
+	5, // [5:8] is the sub-list for method output_type
+	2, // [2:5] is the sub-list for method input_type
+	2, // [2:2] is the sub-list for extension type_name
+	2, // [2:2] is the sub-list for extension extendee
+	0, // [0:2] is the sub-list for field type_name
 }
 
 func init() { file_knowledge_proto_init() }
@@ -199,7 +505,7 @@ func file_knowledge_proto_init() {
 	}
 	if !protoimpl.UnsafeEnabled {
 		file_knowledge_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AddRequest); i {
+			switch v := v.(*Question); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -211,6 +517,18 @@ func file_knowledge_proto_init() {
 			}
 		}
 		file_knowledge_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AddRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_knowledge_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AddResponse); i {
 			case 0:
 				return &v.state
@@ -222,6 +540,42 @@ func file_knowledge_proto_init() {
 				return nil
 			}
 		}
+		file_knowledge_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindAnswerReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_knowledge_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FindAnswerResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_knowledge_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RecommendAnswerResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -229,7 +583,7 @@ func file_knowledge_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_knowledge_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   2,
+			NumMessages:   6,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
@@ -256,6 +610,8 @@ const _ = grpc.SupportPackageIsVersion6
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
 type KnowledgeClient interface {
 	Knowledge(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*AddResponse, error)
+	FindAnswer(ctx context.Context, in *FindAnswerReq, opts ...grpc.CallOption) (*FindAnswerResp, error)
+	RecommendAnswer(ctx context.Context, in *FindAnswerReq, opts ...grpc.CallOption) (*RecommendAnswerResp, error)
 }
 
 type knowledgeClient struct {
@@ -275,9 +631,29 @@ func (c *knowledgeClient) Knowledge(ctx context.Context, in *AddRequest, opts ..
 	return out, nil
 }
 
+func (c *knowledgeClient) FindAnswer(ctx context.Context, in *FindAnswerReq, opts ...grpc.CallOption) (*FindAnswerResp, error) {
+	out := new(FindAnswerResp)
+	err := c.cc.Invoke(ctx, "/template.knowledge/FindAnswer", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *knowledgeClient) RecommendAnswer(ctx context.Context, in *FindAnswerReq, opts ...grpc.CallOption) (*RecommendAnswerResp, error) {
+	out := new(RecommendAnswerResp)
+	err := c.cc.Invoke(ctx, "/template.knowledge/RecommendAnswer", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // KnowledgeServer is the server API for Knowledge service.
 type KnowledgeServer interface {
 	Knowledge(context.Context, *AddRequest) (*AddResponse, error)
+	FindAnswer(context.Context, *FindAnswerReq) (*FindAnswerResp, error)
+	RecommendAnswer(context.Context, *FindAnswerReq) (*RecommendAnswerResp, error)
 }
 
 // UnimplementedKnowledgeServer can be embedded to have forward compatible implementations.
@@ -287,6 +663,12 @@ type UnimplementedKnowledgeServer struct {
 func (*UnimplementedKnowledgeServer) Knowledge(context.Context, *AddRequest) (*AddResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method Knowledge not implemented")
 }
+func (*UnimplementedKnowledgeServer) FindAnswer(context.Context, *FindAnswerReq) (*FindAnswerResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method FindAnswer not implemented")
+}
+func (*UnimplementedKnowledgeServer) RecommendAnswer(context.Context, *FindAnswerReq) (*RecommendAnswerResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RecommendAnswer not implemented")
+}
 
 func RegisterKnowledgeServer(s *grpc.Server, srv KnowledgeServer) {
 	s.RegisterService(&_Knowledge_serviceDesc, srv)
@@ -310,6 +692,42 @@ func _Knowledge_Knowledge_Handler(srv interface{}, ctx context.Context, dec func
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Knowledge_FindAnswer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FindAnswerReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KnowledgeServer).FindAnswer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/template.knowledge/FindAnswer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KnowledgeServer).FindAnswer(ctx, req.(*FindAnswerReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Knowledge_RecommendAnswer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(FindAnswerReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KnowledgeServer).RecommendAnswer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/template.knowledge/RecommendAnswer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KnowledgeServer).RecommendAnswer(ctx, req.(*FindAnswerReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 var _Knowledge_serviceDesc = grpc.ServiceDesc{
 	ServiceName: "template.knowledge",
 	HandlerType: (*KnowledgeServer)(nil),
@@ -318,6 +736,14 @@ var _Knowledge_serviceDesc = grpc.ServiceDesc{
 			MethodName: "knowledge",
 			Handler:    _Knowledge_Knowledge_Handler,
 		},
+		{
+			MethodName: "FindAnswer",
+			Handler:    _Knowledge_FindAnswer_Handler,
+		},
+		{
+			MethodName: "RecommendAnswer",
+			Handler:    _Knowledge_RecommendAnswer_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "knowledge.proto",

+ 18 - 2
rpc/knowledge/knowledgeclient/knowledge.go

@@ -13,11 +13,17 @@ import (
 )
 
 type (
-	AddRequest  = knowledge.AddRequest
-	AddResponse = knowledge.AddResponse
+	FindAnswerReq       = knowledge.FindAnswerReq
+	FindAnswerResp      = knowledge.FindAnswerResp
+	RecommendAnswerResp = knowledge.RecommendAnswerResp
+	Question            = knowledge.Question
+	AddRequest          = knowledge.AddRequest
+	AddResponse         = knowledge.AddResponse
 
 	Knowledge interface {
 		Knowledge(ctx context.Context, in *AddRequest) (*AddResponse, error)
+		FindAnswer(ctx context.Context, in *FindAnswerReq) (*FindAnswerResp, error)
+		RecommendAnswer(ctx context.Context, in *FindAnswerReq) (*RecommendAnswerResp, error)
 	}
 
 	defaultKnowledge struct {
@@ -35,3 +41,13 @@ func (m *defaultKnowledge) Knowledge(ctx context.Context, in *AddRequest) (*AddR
 	client := knowledge.NewKnowledgeClient(m.cli.Conn())
 	return client.Knowledge(ctx, in)
 }
+
+func (m *defaultKnowledge) FindAnswer(ctx context.Context, in *FindAnswerReq) (*FindAnswerResp, error) {
+	client := knowledge.NewKnowledgeClient(m.cli.Conn())
+	return client.FindAnswer(ctx, in)
+}
+
+func (m *defaultKnowledge) RecommendAnswer(ctx context.Context, in *FindAnswerReq) (*RecommendAnswerResp, error) {
+	client := knowledge.NewKnowledgeClient(m.cli.Conn())
+	return client.RecommendAnswer(ctx, in)
+}

+ 2 - 0
rpc/knowledge/logs/access.log

@@ -1,2 +1,4 @@
 {"@timestamp":"2022-06-16T13:55:08.240+08:00","level":"info","content":"info--日志记录"}
 {"@timestamp":"2022-06-16T13:55:08.240+08:00","level":"info","content":"error--日志记录"}
+{"@timestamp":"2022-06-16T15:33:33.547+08:00","level":"info","content":"info--日志记录"}
+{"@timestamp":"2022-06-16T15:33:33.547+08:00","level":"info","content":"error--日志记录"}

+ 196 - 0
rpc/knowledge/logs/stat.log

@@ -0,0 +1,196 @@
+{"@timestamp":"2022-06-16T13:56:08.214+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=6.8Mi, Sys=18.7Mi, NumGC=3"}
+{"@timestamp":"2022-06-16T13:56:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T13:57:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=6.9Mi, Sys=18.7Mi, NumGC=3"}
+{"@timestamp":"2022-06-16T13:57:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T13:58:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=7.1Mi, Sys=18.7Mi, NumGC=4"}
+{"@timestamp":"2022-06-16T13:58:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T13:59:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=7.2Mi, Sys=18.7Mi, NumGC=4"}
+{"@timestamp":"2022-06-16T13:59:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:00:08.214+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=7.3Mi, Sys=18.7Mi, NumGC=5"}
+{"@timestamp":"2022-06-16T14:00:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:01:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=7.4Mi, Sys=18.7Mi, NumGC=5"}
+{"@timestamp":"2022-06-16T14:01:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:02:08.214+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=7.4Mi, Sys=18.7Mi, NumGC=6"}
+{"@timestamp":"2022-06-16T14:02:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:03:08.216+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=7.6Mi, Sys=18.7Mi, NumGC=6"}
+{"@timestamp":"2022-06-16T14:03:08.246+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:04:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=7.7Mi, Sys=18.7Mi, NumGC=7"}
+{"@timestamp":"2022-06-16T14:04:08.249+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:05:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=7.8Mi, Sys=18.7Mi, NumGC=7"}
+{"@timestamp":"2022-06-16T14:05:08.252+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:06:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=7.9Mi, Sys=18.7Mi, NumGC=8"}
+{"@timestamp":"2022-06-16T14:06:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:07:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=8.0Mi, Sys=18.7Mi, NumGC=8"}
+{"@timestamp":"2022-06-16T14:07:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:08:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=8.1Mi, Sys=18.7Mi, NumGC=9"}
+{"@timestamp":"2022-06-16T14:08:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:09:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=8.2Mi, Sys=18.7Mi, NumGC=9"}
+{"@timestamp":"2022-06-16T14:09:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:10:08.220+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=8.3Mi, Sys=18.7Mi, NumGC=10"}
+{"@timestamp":"2022-06-16T14:10:08.251+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:11:08.220+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=8.4Mi, Sys=18.7Mi, NumGC=10"}
+{"@timestamp":"2022-06-16T14:11:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:12:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=8.5Mi, Sys=18.7Mi, NumGC=11"}
+{"@timestamp":"2022-06-16T14:12:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:13:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=8.5Mi, Sys=18.7Mi, NumGC=11"}
+{"@timestamp":"2022-06-16T14:13:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:14:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=8.6Mi, Sys=18.7Mi, NumGC=12"}
+{"@timestamp":"2022-06-16T14:14:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:15:08.215+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=8.7Mi, Sys=18.7Mi, NumGC=12"}
+{"@timestamp":"2022-06-16T14:15:08.246+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:16:08.211+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=8.8Mi, Sys=18.7Mi, NumGC=13"}
+{"@timestamp":"2022-06-16T14:16:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:17:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=8.9Mi, Sys=18.7Mi, NumGC=13"}
+{"@timestamp":"2022-06-16T14:17:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:18:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=9.0Mi, Sys=18.7Mi, NumGC=14"}
+{"@timestamp":"2022-06-16T14:18:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:19:08.216+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=9.1Mi, Sys=18.7Mi, NumGC=14"}
+{"@timestamp":"2022-06-16T14:19:08.247+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:20:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=9.2Mi, Sys=18.7Mi, NumGC=15"}
+{"@timestamp":"2022-06-16T14:20:08.247+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:21:08.217+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=9.3Mi, Sys=18.7Mi, NumGC=15"}
+{"@timestamp":"2022-06-16T14:21:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:22:08.220+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=9.4Mi, Sys=18.7Mi, NumGC=16"}
+{"@timestamp":"2022-06-16T14:22:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:23:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=9.5Mi, Sys=18.7Mi, NumGC=16"}
+{"@timestamp":"2022-06-16T14:23:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:24:08.226+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=9.6Mi, Sys=18.7Mi, NumGC=17"}
+{"@timestamp":"2022-06-16T14:24:08.242+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:25:08.214+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=9.7Mi, Sys=18.7Mi, NumGC=17"}
+{"@timestamp":"2022-06-16T14:25:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:26:08.225+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=9.8Mi, Sys=18.7Mi, NumGC=18"}
+{"@timestamp":"2022-06-16T14:26:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:27:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=9.9Mi, Sys=18.7Mi, NumGC=18"}
+{"@timestamp":"2022-06-16T14:27:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:28:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=10.0Mi, Sys=18.7Mi, NumGC=18"}
+{"@timestamp":"2022-06-16T14:28:08.250+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:29:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=10.1Mi, Sys=18.7Mi, NumGC=19"}
+{"@timestamp":"2022-06-16T14:29:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:30:08.216+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=10.2Mi, Sys=18.7Mi, NumGC=19"}
+{"@timestamp":"2022-06-16T14:30:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:31:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=10.3Mi, Sys=18.7Mi, NumGC=20"}
+{"@timestamp":"2022-06-16T14:31:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:32:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=10.4Mi, Sys=18.7Mi, NumGC=20"}
+{"@timestamp":"2022-06-16T14:32:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:33:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=10.5Mi, Sys=18.7Mi, NumGC=21"}
+{"@timestamp":"2022-06-16T14:33:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:34:08.221+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=10.7Mi, Sys=18.7Mi, NumGC=21"}
+{"@timestamp":"2022-06-16T14:34:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:35:08.219+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=10.7Mi, Sys=18.7Mi, NumGC=22"}
+{"@timestamp":"2022-06-16T14:35:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:36:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=10.8Mi, Sys=18.7Mi, NumGC=22"}
+{"@timestamp":"2022-06-16T14:36:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:37:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=10.9Mi, Sys=18.7Mi, NumGC=23"}
+{"@timestamp":"2022-06-16T14:37:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:38:08.219+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=11.0Mi, Sys=18.7Mi, NumGC=23"}
+{"@timestamp":"2022-06-16T14:38:08.250+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:39:08.226+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=11.1Mi, Sys=18.7Mi, NumGC=24"}
+{"@timestamp":"2022-06-16T14:39:08.242+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:40:08.217+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=11.2Mi, Sys=18.7Mi, NumGC=24"}
+{"@timestamp":"2022-06-16T14:40:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:41:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=11.3Mi, Sys=18.7Mi, NumGC=25"}
+{"@timestamp":"2022-06-16T14:41:08.249+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:42:08.215+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=11.4Mi, Sys=18.7Mi, NumGC=25"}
+{"@timestamp":"2022-06-16T14:42:08.246+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:43:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=11.5Mi, Sys=18.7Mi, NumGC=26"}
+{"@timestamp":"2022-06-16T14:43:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:44:08.226+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=11.6Mi, Sys=18.7Mi, NumGC=26"}
+{"@timestamp":"2022-06-16T14:44:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:45:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=11.7Mi, Sys=18.7Mi, NumGC=27"}
+{"@timestamp":"2022-06-16T14:45:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:46:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=11.8Mi, Sys=18.7Mi, NumGC=27"}
+{"@timestamp":"2022-06-16T14:46:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:47:08.215+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=11.9Mi, Sys=18.7Mi, NumGC=28"}
+{"@timestamp":"2022-06-16T14:47:08.247+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:48:08.219+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=12.0Mi, Sys=18.7Mi, NumGC=28"}
+{"@timestamp":"2022-06-16T14:48:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:49:08.216+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=12.1Mi, Sys=18.7Mi, NumGC=29"}
+{"@timestamp":"2022-06-16T14:49:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:50:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=12.2Mi, Sys=18.7Mi, NumGC=29"}
+{"@timestamp":"2022-06-16T14:50:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:51:08.212+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=12.3Mi, Sys=18.7Mi, NumGC=30"}
+{"@timestamp":"2022-06-16T14:51:08.242+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:52:08.219+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=12.4Mi, Sys=18.7Mi, NumGC=30"}
+{"@timestamp":"2022-06-16T14:52:08.250+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:53:08.219+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=12.5Mi, Sys=18.7Mi, NumGC=31"}
+{"@timestamp":"2022-06-16T14:53:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:54:08.211+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=12.5Mi, Sys=18.7Mi, NumGC=31"}
+{"@timestamp":"2022-06-16T14:54:08.242+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:55:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=12.6Mi, Sys=18.7Mi, NumGC=32"}
+{"@timestamp":"2022-06-16T14:55:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:56:08.215+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=12.7Mi, Sys=18.7Mi, NumGC=32"}
+{"@timestamp":"2022-06-16T14:56:08.246+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:57:08.217+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=12.8Mi, Sys=18.7Mi, NumGC=33"}
+{"@timestamp":"2022-06-16T14:57:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:58:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=12.9Mi, Sys=18.7Mi, NumGC=33"}
+{"@timestamp":"2022-06-16T14:58:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T14:59:08.226+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=13.0Mi, Sys=18.7Mi, NumGC=34"}
+{"@timestamp":"2022-06-16T14:59:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:00:08.217+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=13.1Mi, Sys=18.7Mi, NumGC=34"}
+{"@timestamp":"2022-06-16T15:00:08.247+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:01:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=13.2Mi, Sys=18.7Mi, NumGC=35"}
+{"@timestamp":"2022-06-16T15:01:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:02:08.223+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=13.3Mi, Sys=18.7Mi, NumGC=35"}
+{"@timestamp":"2022-06-16T15:02:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:03:08.214+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=13.4Mi, Sys=18.7Mi, NumGC=36"}
+{"@timestamp":"2022-06-16T15:03:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:04:08.215+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=13.5Mi, Sys=18.7Mi, NumGC=36"}
+{"@timestamp":"2022-06-16T15:04:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:05:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=13.6Mi, Sys=18.7Mi, NumGC=37"}
+{"@timestamp":"2022-06-16T15:05:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:06:08.219+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=13.8Mi, Sys=18.7Mi, NumGC=37"}
+{"@timestamp":"2022-06-16T15:06:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:07:08.225+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=13.8Mi, Sys=18.7Mi, NumGC=38"}
+{"@timestamp":"2022-06-16T15:07:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:08:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=13.9Mi, Sys=18.7Mi, NumGC=38"}
+{"@timestamp":"2022-06-16T15:08:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:09:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=14.0Mi, Sys=18.7Mi, NumGC=39"}
+{"@timestamp":"2022-06-16T15:09:08.254+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:10:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=14.1Mi, Sys=18.7Mi, NumGC=39"}
+{"@timestamp":"2022-06-16T15:10:08.250+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:11:08.216+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=14.2Mi, Sys=18.7Mi, NumGC=40"}
+{"@timestamp":"2022-06-16T15:11:08.247+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:12:08.225+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=14.3Mi, Sys=18.7Mi, NumGC=40"}
+{"@timestamp":"2022-06-16T15:12:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:13:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=14.4Mi, Sys=18.7Mi, NumGC=41"}
+{"@timestamp":"2022-06-16T15:13:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:14:08.212+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=14.4Mi, Sys=18.7Mi, NumGC=41"}
+{"@timestamp":"2022-06-16T15:14:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:15:08.211+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=14.5Mi, Sys=18.7Mi, NumGC=42"}
+{"@timestamp":"2022-06-16T15:15:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:16:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=14.6Mi, Sys=18.7Mi, NumGC=42"}
+{"@timestamp":"2022-06-16T15:16:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:17:08.227+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=14.7Mi, Sys=18.7Mi, NumGC=43"}
+{"@timestamp":"2022-06-16T15:17:08.242+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:18:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=14.8Mi, Sys=18.7Mi, NumGC=43"}
+{"@timestamp":"2022-06-16T15:18:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:19:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=14.9Mi, Sys=18.7Mi, NumGC=44"}
+{"@timestamp":"2022-06-16T15:19:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:20:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=15.0Mi, Sys=18.7Mi, NumGC=44"}
+{"@timestamp":"2022-06-16T15:20:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:21:08.212+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=15.1Mi, Sys=18.7Mi, NumGC=45"}
+{"@timestamp":"2022-06-16T15:21:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:22:08.225+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=15.2Mi, Sys=18.7Mi, NumGC=45"}
+{"@timestamp":"2022-06-16T15:22:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:23:08.212+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=15.3Mi, Sys=18.7Mi, NumGC=46"}
+{"@timestamp":"2022-06-16T15:23:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:24:08.216+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=15.4Mi, Sys=18.7Mi, NumGC=46"}
+{"@timestamp":"2022-06-16T15:24:08.247+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:25:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=15.5Mi, Sys=18.7Mi, NumGC=47"}
+{"@timestamp":"2022-06-16T15:25:08.243+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:26:08.226+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=15.6Mi, Sys=18.7Mi, NumGC=47"}
+{"@timestamp":"2022-06-16T15:26:08.242+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:27:08.217+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=15.7Mi, Sys=18.7Mi, NumGC=48"}
+{"@timestamp":"2022-06-16T15:27:08.248+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:28:08.224+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=15.8Mi, Sys=18.7Mi, NumGC=48"}
+{"@timestamp":"2022-06-16T15:28:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:29:08.218+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=15.9Mi, Sys=18.7Mi, NumGC=49"}
+{"@timestamp":"2022-06-16T15:29:08.241+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:30:08.212+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=16.0Mi, Sys=18.7Mi, NumGC=49"}
+{"@timestamp":"2022-06-16T15:30:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:31:08.222+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=16.1Mi, Sys=18.7Mi, NumGC=50"}
+{"@timestamp":"2022-06-16T15:31:08.240+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:32:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.5Mi, TotalAlloc=16.2Mi, Sys=18.7Mi, NumGC=50"}
+{"@timestamp":"2022-06-16T15:32:08.245+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}
+{"@timestamp":"2022-06-16T15:33:08.213+08:00","level":"stat","content":"CPU: 0m, MEMORY: Alloc=3.4Mi, TotalAlloc=16.3Mi, Sys=18.7Mi, NumGC=51"}
+{"@timestamp":"2022-06-16T15:33:08.244+08:00","level":"stat","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0"}

+ 175 - 0
rpc/knowledge/utils/elasticsearch_dsl.go

@@ -0,0 +1,175 @@
+package utils
+
+import (
+	"fmt"
+	. "knowledgeBase/rpc/knowledge/init"
+	"log"
+	"strings"
+)
+
+var (
+	Analyze string
+	Segment string
+)
+
+/*项目中所用到的几类查询dsl语句构建工具类*/
+
+// DSL4SearchByKwsAndTags 管理后台列表查询
+func DSL4SearchByKwsAndTags(kws string, tags ...string) string {
+	var (
+		sql        = `{"query": {"bool": {"must": [%s,%s]}}}`
+		queryMatch = `{"match":{"knowledgeKeyWords":{"query":"%s","minimum_should_match":"%s"}}}`
+		tagsTerms  = `{"terms":{"tags.code":[%s]}}`
+		tag        = `"%s"`
+	)
+	if kws != "" {
+
+	}
+	queryMatch = fmt.Sprintf(queryMatch, kws, "20%")
+	tmp := ""
+	for i, val := range tags {
+		if i < len(tags)-1 {
+			tmp += fmt.Sprintf(tag, val) + ","
+		} else {
+			tmp += fmt.Sprintf(tag, val)
+		}
+	}
+	tagsTerms = fmt.Sprintf(tagsTerms, tmp)
+	sql = fmt.Sprintf(sql, queryMatch, tagsTerms)
+	return sql
+}
+
+func DSL4SmartResponse(question, tenantId string, msgType int) string {
+	var (
+		totalQuery = `{"post_filter":{%s},"query":{%s},"_source":["_id"%s],"size":%d}`
+		postFilter = `"script":{"script":"def sk=_source.must_keywords;def n=0;for(item in sk){ n++;if(que.indexOf(item)>-1){return true}};if(n==0){ return true}","params":{"que":"%s"}}`
+		query      = `"bool":{"must_not":[%s],"must":[{"match":{"%s":{"query":"%s","minimum_should_match":"%s"}}},{"terms":{"tenantId":"%s"}}]}`
+	)
+	var typeStr string
+	/*1.首先将问题使用hanlp分词*/
+	//hanlpCutWords := HanlpGetNormalWords(question, "http://39.106.145.77:8080/api/segment")
+	hanlpCutWords := HanlpGetNormalWords(question, C.Segment)
+	question = strings.Join(hanlpCutWords, "")
+	//fmt.Println("question:", question)
+	lenQuestion := len([]rune(question))
+	if lenQuestion >= 2 {
+		queryPercent := "40%"
+		if lenQuestion < 5 {
+			queryPercent = "85%"
+		} else if lenQuestion < 9 {
+			queryPercent = "60%"
+		} else if lenQuestion < 12 {
+			queryPercent = "55%"
+		}
+		if msgType == 1 {
+			typeStr = "knowledgeKeyWords"
+		} else if msgType == 2 { //百度语音过来的
+			typeStr = "knowledgeKeyWords.key_pinyin"
+		}
+		/*2使用sik分词将问题分词以获取更多查询词语*/
+		//mustque := ElasticSmartIK(question, "http://39.106.145.77:9201/smart/_analyze")
+		mustque := ElasticSmartIK(question, Analyze)
+		if mustque != "" {
+			postFilter = fmt.Sprintf(postFilter, mustque)
+		}
+		query = fmt.Sprintf(query, "", typeStr, question, queryPercent, tenantId)
+		queryDSL := fmt.Sprintf(totalQuery, postFilter, query, `,"answer","questions","_id"`, 1)
+		//log.Println("queryDSL:", queryDSL)
+		return queryDSL
+	}
+	return ""
+}
+
+func DSL4SmartResponseList(question, msgType string, repositoryId []string, must_not string, size int, tags ...string) string {
+	queryPercent := "20%"
+	var (
+		totalQuery = `{"post_filter":{%s},"query":{%s},"_source":["_id"%s],"size":%d}`
+		postFilter = `"script":{"script":"def sk=_source.must_keywords;def n=0;for(item in sk){ n++;if(que.indexOf(item)>-1){return true}};if(n==0){ return true}","params":{"que":"%s"}}`
+		query      = `"bool":{"must_not":[%s],"must":[{"match":{"%s":{"query":"%s","minimum_should_match":"%s"}}},{"terms":{"repositoryId":%s}},{"terms":{"tags.code":[%s]}}]}`
+	)
+	/*2使用sik分词将问题分词以获取更多查询词语*/
+	//mustque := ElasticSmartIK(question, "http://39.106.145.77:9201/smart/_analyze")
+	mustque := ElasticSmartIK(question, Analyze)
+	if mustque != "" {
+		postFilter = fmt.Sprintf(postFilter, mustque)
+	}
+	tmp := ""
+	for i, val := range tags {
+		if i < len(tags)-1 {
+			tmp += fmt.Sprintf(`"%s"`, val) + ","
+		} else {
+			tmp += fmt.Sprintf(`"%s"`, val)
+		}
+	}
+	query = fmt.Sprintf(query, must_not, msgType, question, queryPercent, repositoryId, tmp)
+	queryDSL := fmt.Sprintf(totalQuery, postFilter, query, `,"answer","questions.question"`, size)
+	log.Println("queryDSL:", queryDSL)
+	return queryDSL
+}
+
+func DSL4SearchByKwsOrid(kws, _id string, repositoryArr []string) string {
+
+	var (
+		sql        = `{"query": {"bool": {"must": [%s%s]}}}`
+		queryMatch = `{"match":{"knowledgeKeyWords":{"query":"%s","minimum_should_match":"%s"}}}`
+		idTerms    = `,{"terms":{"smart.id":[%s]}}`
+		ridTerms   = `,{"terms":{"repositoryId":%s}}`
+		id         = `"%s"`
+	)
+	queryMatch = fmt.Sprintf(queryMatch, kws, "20%")
+	//fmt.Println("queryMatch:", queryMatch)
+	tmp := ""
+	if _id != "" {
+		tmp = fmt.Sprintf(id, _id)
+		idTerms = fmt.Sprintf(idTerms, tmp, repositoryArr)
+		sql = fmt.Sprintf(sql, queryMatch, idTerms)
+	} else {
+		ridTerms = fmt.Sprintf(ridTerms, repositoryArr)
+		sql = fmt.Sprintf(sql, queryMatch, ridTerms)
+	}
+	log.Println("sql", sql)
+	return sql
+}
+
+func GetQueryOT(tags, question, keywords, repositoryId string) (qstr string) {
+	var query = `{"query":{"bool":{"must":[%s%s%s%s]}}}`
+	queryMatch := ``
+	queryTerms := ``
+	queryId := ``
+	queryQues := ``
+	if keywords != "" {
+		queryMatch = `{"match":{"knowledgeKeyWords":{"query":"` + keywords + `","minimum_should_match":"40%"}}},`
+		//query_match = `{"match":{"questions.question":{"query":"` + keywords + `","minimum_should_match":"20%"}}},`
+	}
+	tags = strings.Replace(tags, ` `, `","`, -1)
+	if tags != "" {
+		queryTerms = `{"terms":{"tags.code":["` + tags + `"]}},`
+	}
+	if repositoryId != "" {
+		queryId = `{"terms":{"repositoryId":[` + repositoryId + `]}}`
+	}
+	if question != "" {
+		queryQues = `,{"match": {"smart.questions.question": {"query": "` + question + `","fuzziness": "AUTO","operator": "and"}}}`
+	}
+	qstr = fmt.Sprintf(query, queryMatch, queryTerms, queryId, queryQues)
+	return qstr
+}
+
+/*func GetFindQuery(keywords, tags, repositoryId string) string {
+	var query = `{"query":{"bool":{"must":[%s%s%s]}}}`
+	query_match := ``
+	query_terms := ``
+	query_id := ``
+	if keywords != "" {
+		query_match = `{"match":{"knowledgeKeyWords":{"query":"` + keywords + `","minimum_should_match":"40%"}}},`
+	}
+	tags = strings.Replace(tags, ` `, `","`, -1)
+	if tags != "" {
+		query_terms = `{"terms":{"tags.code":["` + tags + `"]}},`
+	}
+	if repositoryId != "" {
+		query_id = `{"terms":{"repositoryId":[` + repositoryId + `]}}`
+	}
+	qstr := fmt.Sprintf(query, query_match, query_terms, query_id)
+	return qstr
+}*/

+ 166 - 0
rpc/knowledge/utils/hanlp.go

@@ -0,0 +1,166 @@
+package utils
+
+import (
+	cm "app.yhyue.com/moapp/jybase/common"
+	"encoding/base64"
+	"encoding/json"
+	"io/ioutil"
+	. "knowledgeBase/rpc/knowledge/init"
+	"log"
+	"net/http"
+	"net/url"
+	"regexp"
+	"strings"
+)
+
+/*hanlp分词工具类*/
+
+var hanlpNormalKindOfWordsReg = regexp.MustCompile("[nvmqa]")
+var hanlpRegTail = regexp.MustCompile("[??.。!!,,;;]+$")
+var hanlpWordsFilter = []string{"请问", "如何", "应该", "怎么办", "怎么", "需要", "想", "要", "是", "有", "有何", "可有"}
+var hanlpWordsFilterMap = make(map[string]bool, 0)
+
+//var Encrypt = &SimpleEncrypt{Key: "Smart20180502_!"}
+
+func init() {
+	for _, val := range hanlpWordsFilter {
+		hanlpWordsFilterMap[val] = true
+	}
+}
+func getResult(str, url string) []map[string]interface{} {
+	var (
+		bs     []byte
+		err    error
+		resMap []map[string]interface{}
+	)
+	str = hanlpRegTail.ReplaceAllString(str, "")
+	resp, _ := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader("content="+str))
+	bs, err = ioutil.ReadAll(resp.Body)
+	if err != nil {
+		log.Printf("获取hanlp分词结果出错:[%v]", err)
+		return resMap
+	}
+	err = json.Unmarshal(bs, &resMap)
+	if err != nil {
+		log.Printf("获取hanlp分词json解码出错:[%v]", err)
+	}
+	return resMap
+}
+
+// HanlpGetNoun 获取名词分词词组
+func HanlpGetNoun(words, url string) []string {
+	var (
+		data = make([]string, 0)
+	)
+	baseResult := getResult(words, url)
+	if len(baseResult) > 0 {
+		for _, v := range baseResult {
+			if strings.Contains(v["nature"].(string), "n") && len(v["word"].(string)) > 2 {
+				data = append(data, v["word"].(string))
+			}
+		}
+	}
+	return data
+}
+
+/*获取nvmqa5类分词词组*/
+func HanlpGetNormalWords(words, url string) []string {
+	var (
+		data = make([]string, 0)
+	)
+	baseResult := getResult(words, url)
+	if len(baseResult) > 0 {
+		for _, v := range baseResult {
+			w, _ := v["word"].(string)
+			if !hanlpWordsFilterMap[w] {
+				n, _ := v["nature"].(string)
+				n = strings.ToLower(n)
+				if hanlpNormalKindOfWordsReg.MatchString(n) && len([]rune(w)) > 0 {
+					data = append(data, w)
+				}
+			}
+		}
+	}
+	return data
+}
+
+func ElasticSmartIK(words, urls string) (res string) {
+	URL, _ := url.Parse(urls)
+	Q := URL.Query()
+	Q.Add("text", words)
+	Q.Add("analyzer", "sik")
+	URL.RawQuery = Q.Encode()
+	resp, err := http.Get(URL.String())
+	if err != nil {
+		log.Println("ElasticSmartIK error:", err)
+	} else {
+		result, err := ioutil.ReadAll(resp.Body)
+		if err == nil {
+			defer resp.Body.Close()
+			var resmap map[string]interface{}
+			err = json.Unmarshal(result, &resmap)
+			if err != nil {
+				log.Println("ElasticSmartIK json解码 error:", err)
+			}
+			if resmap != nil {
+				tokens := cm.ObjArrToMapArr(resmap["tokens"].([]interface{}))
+				for _, v := range tokens {
+					res += v["token"].(string)
+				}
+			}
+		}
+	}
+	return
+}
+
+// HttpDo smartInfo中用到,对问题分词
+func HttpDo(ques string) (result string) {
+	client := &http.Client{}
+	//req, err := http.NewRequest("POST", "http://39.106.145.77:8080/api/segment", strings.NewReader("content="+ques))
+	req, err := http.NewRequest("POST", C.Segment, strings.NewReader("content="+ques))
+	if err != nil {
+		log.Println("err1:")
+	}
+
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	resp, err := client.Do(req)
+
+	defer resp.Body.Close()
+
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		log.Println("err2:")
+	}
+	return string(body)
+}
+
+type SimpleEncrypt struct {
+	Key string //加解密用到的key(加密key索引)+
+}
+
+func (s *SimpleEncrypt) EncodeString(str string) string {
+	data := []byte(str)
+	s.doEncode(data)
+	return base64.StdEncoding.EncodeToString(data)
+}
+
+// DecodeString 解密String
+func (s *SimpleEncrypt) DecodeString(str string) string {
+	data, _ := base64.StdEncoding.DecodeString(str)
+	s.doEncode(data)
+	return string(data)
+}
+
+func (s *SimpleEncrypt) doEncode(bs []byte) {
+	tmp := []byte(s.Key)
+THEFOR:
+	for i := 0; i < len(bs); {
+		for j := 0; j < len(tmp); j, i = j+1, i+1 {
+			if i >= len(bs) {
+				break THEFOR
+			}
+			bs[i] = bs[i] ^ tmp[j]
+		}
+	}
+}