package stdlib import ( "app.yhyue.com/moapp/jy_docs/services/partner" "fmt" "log" "regexp" "strings" "time" "app.yhyue.com/moapp/jy_docs/rpc/stdlib/stdlib" "app.yhyue.com/moapp/jy_docs/services/model" jyDocsRpcUtil "app.yhyue.com/moapp/jy_docs/services/util" "app.yhyue.com/moapp/jybase/common" elastic "app.yhyue.com/moapp/jybase/esv7" ) const ( Es_Query_All = `{"query":{"match_all":{}}%s}` Es_Query_Boosting = `{"query":{"boosting":{"positive":{"bool":{"must":[%s]}},"negative":{"bool":{"must":[%s]}},"negative_boost":2}}%s}` Es_Query_Bool = `{"query":{"bool":{"filter":[%s]}}%s}` Es_Query_Append = `,"_source":["id","docName","price","downTimes","viewTimes","docSummary","uploadDate","docFileSize","docPageSize","docFileType","previewImgId","source","productType","docTags"],"from":%d,"size":%d` Es_Query_Highlight = `,"highlight":{"fields":{"docName":{},"docSummary":{"fragment_size":300,"number_of_fragments":1}}}` Es_Query_Sort = `,"sort":{%s}` Multi_Match = `{"multi_match":{"query":"%s","fields":["docName","docSummary^2"]}}` Multi_Match_Phrase = `{"multi_match":{"query":"%s","fields":["docName.docName_c","docSummary.docSummary_c"],"type":"phrase"}}` Terms = `{"terms":{"%s":[%s]}}` Term = `{"term":{"%s":%s}}` ) var ( Reg = regexp.MustCompile(`\s+`) ) func FindDocumentById(id int) { log.Println(jyDocsRpcUtil.GetJyDocsDB().Exec("select * from ").Error) } func DocQuery(in *stdlib.DocQueryRequest) *stdlib.DocQueryResponse { startNow := time.Now() defer common.Catch() in.KeyWord = strings.TrimSpace(in.KeyWord) musts := []string{} negative_musts := []string{} sorts := []string{} //搜索词 if in.KeyWord != "" { sorts = append(sorts, `"_score":"desc"`) for _, v := range strings.Split(in.KeyWord, " ") { v = strings.ReplaceAll(v, `"`, `\"`) musts = append(musts, fmt.Sprintf(Multi_Match, v)) negative_musts = append(negative_musts, fmt.Sprintf(Multi_Match_Phrase, v)) } } for _, v := range in.Sort { if strings.HasPrefix(v, "-") { sorts = append(sorts, fmt.Sprintf(`"%s":"desc"`, strings.TrimLeft(v, "-"))) } else { sorts = append(sorts, fmt.Sprintf(`"%s":"asc"`, v)) } } //分类 if len(in.DocClass) > 0 { musts = append(musts, fmt.Sprintf(Terms, "docClass", `"`+strings.Join(in.DocClass, `","`)+`"`)) } //标签 if len(in.DocTag) > 0 { musts = append(musts, fmt.Sprintf(Terms, "docTags", `"`+strings.Join(in.DocTag, `","`)+`"`)) } // 文件类型 if in.DocFileType > 0 { musts = append(musts, fmt.Sprintf(Term, "docFileType", `"`+fmt.Sprintf("%d", in.DocFileType)+`"`)) } // 商品类型 if in.ProductType > 0 { musts = append(musts, fmt.Sprintf(Term, "productType", `"`+fmt.Sprintf("%d", in.ProductType)+`"`)) } query := "" query_sort := "" if len(sorts) > 0 { query_sort = fmt.Sprintf(Es_Query_Sort, strings.Join(sorts, ",")) } query_append := fmt.Sprintf(Es_Query_Append, (in.PageNum-1)*in.PageSize, in.PageSize) if len(musts) == 0 { query = fmt.Sprintf(Es_Query_All, fmt.Sprint(query_append, query_sort)) } else if in.KeyWord != "" { query = fmt.Sprintf(Es_Query_Boosting, strings.Join(musts, ","), strings.Join(negative_musts, ","), fmt.Sprint(query_append, query_sort, Es_Query_Highlight)) } else { query = fmt.Sprintf(Es_Query_Bool, strings.Join(musts, ","), fmt.Sprint(query_append, query_sort)) } log.Println("query:", query) total, list := elastic.GetBySearchType(model.Es_JyDoc, "dfs_query_then_fetch", query) log.Println("es 查询耗时:", time.Since(startNow)) step2 := time.Now() docs := []*stdlib.Doc{} //获取我购买的文档 if list != nil { myDocs := map[string]int64{} if in.UserId != "" { docIds, whs := []interface{}{}, []string{} for _, v := range *list { whs = append(whs, "?") docIds = append(docIds, common.ObjToString(v["id"])) } args := []interface{}{in.UserId, model.UserDocStatus_Normal, in.AppId} args = append(args, docIds...) userDocs := []*model.UserDoc{} jyDocsRpcUtil.GetJyDocsDB().Exec(`select docId from user_doc where userId=? and isDelete=? and appId=? and isDownload=1 and docId in (`+strings.Join(whs, ",")+`)`, args...).Find(&userDocs) for _, v := range userDocs { myDocs[v.DocId] = 1 } } for _, v := range *list { tags := strings.Split(common.ObjToString(v["docTags"]), ",") tmptags := []string{} subTag := "" //step3 := time.Now() for i := 0; i < len(tags); i++ { dtpKey := fmt.Sprintf("p_%s_0_tag", tags[i]) //一级tag if _, ok := partner.DocClassMap[dtpKey]; ok && len(tmptags) == 0 { tmptags = append(tmptags, tags[i]) } else { subTag = tags[i] } if subTag != "" && len(tmptags) > 0 { tmptags = append(tmptags, subTag) break } } //log.Println("step3", time.Since(step3)) doc := &stdlib.Doc{ DocId: common.ObjToString(v["id"]), DocName: common.ObjToString(v["docName"]), DocPageSize: common.Int64All(v["docPageSize"]), DocFileSize: common.Int64All(v["docFileSize"]), DownTimes: common.Int64All(v["downTimes"]), ViewTimes: common.Int64All(v["viewTimes"]), UploadDate: common.ObjToString(v["uploadDate"]), DocSummary: common.ObjToString(v["docSummary"]), DocFileType: model.DocFileType[common.IntAll(v["docFileType"])], PreviewImgId: common.InterfaceToStr(v["previewImgId"]), ProductType: common.Int64All(v["productType"]), Source: common.Int64All(v["source"]), DocTags: strings.Join(tmptags, " "), } highlight, _ := v["highlight"].(map[string][]string) if len(highlight["docName"]) > 0 { doc.DocName = highlight["docName"][0] } if len(highlight["docSummary"]) > 0 { doc.DocSummary = highlight["docSummary"][0] } doc.IsDownload = myDocs[doc.DocId] docs = append(docs, doc) } } log.Println("step2", time.Since(step2)) log.Println("end", time.Since(startNow)) return &stdlib.DocQueryResponse{ Total: total, Docs: docs, Code: 1, } }