elastic.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package services
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/olivere/elastic/v7"
  7. "hongze/hongze_clpt/models"
  8. "hongze/hongze_clpt/utils"
  9. "strconv"
  10. )
  11. //func NewClient() (client *elastic.Client, err error) {
  12. // //errorlog := log.New(os.Stdout, "APP", log.LstdFlags)
  13. // //file := ""
  14. // //if utils.RunMode == "release" {
  15. // // //file = `/data/rdlucklog/hongze_cygx/eslog.log`
  16. // // file = `./rdlucklog/eslog.log`
  17. // //} else {
  18. // // file = `./rdlucklog/eslog.log`
  19. // //}
  20. // //logFile, _ := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
  21. // //client, err = elastic.NewClient(
  22. // // elastic.SetURL(ES_URL),
  23. // // elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
  24. // // elastic.SetTraceLog(log.New(logFile, "ES-TRACE: ", 0)),
  25. // // elastic.SetSniff(false), elastic.SetErrorLog(errorlog))
  26. // client, err = elastic.NewClient(
  27. // elastic.SetURL(ES_URL),
  28. // elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
  29. // elastic.SetSniff(false))
  30. // return
  31. //}
  32. func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
  33. a_len := len(a)
  34. for i := 0; i < a_len; i++ {
  35. if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
  36. continue
  37. }
  38. ret = append(ret, a[i])
  39. }
  40. return
  41. }
  42. func GetArrSum(intArr []int) (sum int) {
  43. for _, val := range intArr {
  44. //累计求和
  45. sum += val
  46. }
  47. return
  48. }
  49. func EsMultiMatchFunctionScoreQuerySort(indexName, keyWord string, startSize, pageSize, userId int, orderColumn string) (result []*models.SearchItem, total int64, err error) {
  50. client := utils.Client
  51. keyWordArr, err := GetIndustryMapNameSliceV3(keyWord)
  52. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  53. //artidArr := make([]elastic.Query, 0)
  54. //matchArr := make([]elastic.Query, 0)
  55. n := 0
  56. keyWordLen := len(keyWordArr)
  57. if keyWordLen <= 0 {
  58. keyWordArr = append(keyWordArr, keyWord)
  59. keyWordLen = len(keyWordArr)
  60. }
  61. // @Param OrderColumn query int true "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
  62. utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
  63. //keyWordWeight := GetWeight(keyWordLen)
  64. for _, v := range keyWordArr {
  65. if v != "" {
  66. matchArr := make([]elastic.Query, 0)
  67. boolquery := elastic.NewBoolQuery()
  68. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  69. bodyFunctionQuery2 := elastic.NewFunctionScoreQuery()
  70. bodyFunctionQuery3 := elastic.NewFunctionScoreQuery()
  71. //multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText").Analyzer("ik_smart")
  72. multiMatch := elastic.NewMultiMatchQuery(v, "Title").Analyzer("ik_smart").Boost(100)
  73. bodyFunctionQuery.Query(multiMatch)
  74. matchArr = append(matchArr, bodyFunctionQuery)
  75. multiMatch = elastic.NewMultiMatchQuery(v, "BodyText").Analyzer("ik_smart").Boost(1)
  76. bodyFunctionQuery2.Query(multiMatch)
  77. matchArr = append(matchArr, bodyFunctionQuery2)
  78. //multiMatch = elastic.NewMultiMatchQuery(1, "IsSummary")
  79. bodyFunctionQuery3.Query(multiMatch)
  80. matchArr = append(matchArr, bodyFunctionQuery3)
  81. boolquery.Should(matchArr...)
  82. //multiMatch = elastic.NewMultiMatchQuery(v, "BodyText").Analyzer("ik_smart")
  83. //bodyFunctionQuery.Query(multiMatch)
  84. //matchArr = append(matchArr, bodyFunctionQuery)
  85. //boolquery.Should(matchArr...)
  86. highlight := elastic.NewHighlight()
  87. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  88. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  89. request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).From(0).Size(pageSize).Query(boolquery)
  90. if orderColumn == "Matching" {
  91. request = client.Search(indexName).Highlight(highlight).From(0).Size(pageSize).Query(boolquery)
  92. }
  93. searchByMatch, err := request.Do(context.Background())
  94. if err != nil {
  95. return nil, 0, err
  96. }
  97. if searchByMatch != nil {
  98. if searchByMatch.Hits != nil {
  99. for _, v := range searchByMatch.Hits.Hits {
  100. var isAppend bool
  101. articleJson, err := v.Source.MarshalJSON()
  102. if err != nil {
  103. return nil, 0, err
  104. }
  105. article := new(models.CygxArticleEs)
  106. err = json.Unmarshal(articleJson, &article)
  107. if err != nil {
  108. return nil, 0, err
  109. }
  110. searchItem := new(models.SearchItem)
  111. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  112. if len(v.Highlight["BodyText"]) > 0 {
  113. searchItem.Body = v.Highlight["BodyText"]
  114. } else {
  115. bodyRune := []rune(article.BodyText)
  116. bodyRuneLen := len(bodyRune)
  117. if bodyRuneLen > 100 {
  118. bodyRuneLen = 100
  119. }
  120. body := string(bodyRune[:bodyRuneLen])
  121. searchItem.Body = []string{body}
  122. }
  123. var title string
  124. if len(v.Highlight["Title"]) > 0 {
  125. title = v.Highlight["Title"][0]
  126. } else {
  127. title = article.Title
  128. }
  129. searchItem.Title = title
  130. searchItem.PublishDate = article.PublishDate
  131. searchItem.ExpertBackground = article.ExpertBackground
  132. searchItem.CategoryId = article.CategoryId
  133. for _, v_result := range result {
  134. if v_result.ArticleId == searchItem.ArticleId {
  135. isAppend = true
  136. }
  137. }
  138. if !isAppend {
  139. result = append(result, searchItem)
  140. }
  141. }
  142. }
  143. //total += searchByMatch.Hits.TotalHits.Value
  144. }
  145. }
  146. n++
  147. }
  148. total = int64(len(result))
  149. return
  150. }
  151. func EsMultiMatchFunctionScoreQueryTimeSort(indexName, keyWord string, startSize, pageSize, userId int) (result []*models.SearchItem, total int64, err error) {
  152. client := utils.Client
  153. keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
  154. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  155. boolquery := elastic.NewBoolQuery()
  156. matchArr := make([]elastic.Query, 0)
  157. //matchArr2 := make([]elastic.Query, 0)
  158. n := 0
  159. keyWordLen := len(keyWordArr)
  160. if keyWordLen <= 0 {
  161. keyWordArr = append(keyWordArr, keyWord)
  162. keyWordLen = len(keyWordArr)
  163. }
  164. utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
  165. for _, v := range keyWordArr {
  166. if v != "" {
  167. multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText")
  168. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  169. bodyFunctionQuery.Query(multiMatch)
  170. matchArr = append(matchArr, bodyFunctionQuery)
  171. }
  172. n++
  173. }
  174. boolquery.Should(matchArr...)
  175. highlight := elastic.NewHighlight()
  176. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  177. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  178. request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).Size(pageSize).Query(boolquery)
  179. searchByMatch, err := request.Do(context.Background())
  180. if searchByMatch != nil {
  181. matchResult, _ := json.Marshal(searchByMatch)
  182. utils.FileLog.Info("%s", string(matchResult))
  183. fmt.Println(len(searchByMatch.Hits.Hits))
  184. if searchByMatch.Hits != nil {
  185. for _, v := range searchByMatch.Hits.Hits {
  186. articleJson, err := v.Source.MarshalJSON()
  187. utils.FileLog.Info("%s", string(articleJson))
  188. if err != nil {
  189. return nil, 0, err
  190. }
  191. article := new(models.CygxArticleEs)
  192. err = json.Unmarshal(articleJson, &article)
  193. if err != nil {
  194. return nil, 0, err
  195. }
  196. searchItem := new(models.SearchItem)
  197. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  198. if len(v.Highlight["BodyText"]) > 0 {
  199. searchItem.Body = v.Highlight["BodyText"]
  200. } else {
  201. bodyRune := []rune(article.BodyText)
  202. bodyRuneLen := len(bodyRune)
  203. if bodyRuneLen > 100 {
  204. bodyRuneLen = 100
  205. }
  206. body := string(bodyRune[:bodyRuneLen])
  207. searchItem.Body = []string{body}
  208. }
  209. var title string
  210. if len(v.Highlight["Title"]) > 0 {
  211. title = v.Highlight["Title"][0]
  212. } else {
  213. title = article.Title
  214. }
  215. searchItem.Title = title
  216. searchItem.PublishDate = article.PublishDate
  217. searchItem.ExpertBackground = article.ExpertBackground
  218. searchItem.CategoryId = article.CategoryId
  219. result = append(result, searchItem)
  220. }
  221. }
  222. total = searchByMatch.Hits.TotalHits.Value
  223. }
  224. return
  225. }
  226. func EsArticleSearch(keyWord string, startSize, pageSize int, orderColumn string) (result []*models.SearchItem, total int64, err error) {
  227. indexName := utils.IndexName
  228. client := utils.Client
  229. keyWordArr, err := GetIndustryMapNameSliceV3(keyWord)
  230. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  231. keyWordLen := len(keyWordArr)
  232. if keyWordLen <= 0 {
  233. keyWordArr = append(keyWordArr, keyWord)
  234. keyWordLen = len(keyWordArr)
  235. }
  236. mustMap := make([]interface{}, 0)
  237. shouldMap := make(map[string]interface{}, 0)
  238. shouldMapquery := make([]interface{}, 0)
  239. // @Param OrderColumn query int true "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
  240. //keyWordWeight := GetWeight(keyWordLen)
  241. var boost int
  242. lenkeyWordArr := len(keyWordArr)
  243. for k, v := range keyWordArr {
  244. if k == 0 {
  245. boost = 2 * 1000
  246. } else {
  247. boost = 1000
  248. }
  249. if v != "" {
  250. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  251. "function_score": map[string]interface{}{
  252. "query": map[string]interface{}{
  253. "multi_match": map[string]interface{}{
  254. "boost": (lenkeyWordArr - k) * boost, //给查询的值赋予权重
  255. "fields": []interface{}{"Title"},
  256. "query": v,
  257. },
  258. },
  259. },
  260. })
  261. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  262. "function_score": map[string]interface{}{
  263. "query": map[string]interface{}{
  264. "multi_match": map[string]interface{}{
  265. "boost": (lenkeyWordArr-k)*boost - 1, //给查询的值赋予权重
  266. "fields": []interface{}{"BodyText"},
  267. "query": v,
  268. },
  269. },
  270. },
  271. })
  272. }
  273. }
  274. shouldMap = map[string]interface{}{
  275. "should": shouldMapquery,
  276. }
  277. //排序
  278. sortMap := make([]interface{}, 0)
  279. //时间
  280. sortMap = append(sortMap, map[string]interface{}{
  281. "PublishDate": map[string]interface{}{
  282. "order": "desc",
  283. },
  284. })
  285. //高亮
  286. highlightMap := make(map[string]interface{}, 0)
  287. highlightMap = map[string]interface{}{
  288. "fields": map[string]interface{}{
  289. "BodyText": map[string]interface{}{},
  290. "Title": map[string]interface{}{},
  291. },
  292. //样式 红色
  293. "post_tags": []interface{}{"</font>"},
  294. "pre_tags": []interface{}{"<font color='red'>"},
  295. }
  296. mustMap = append(mustMap, map[string]interface{}{
  297. "bool": shouldMap,
  298. })
  299. queryMap := map[string]interface{}{
  300. "query": map[string]interface{}{
  301. "bool": map[string]interface{}{
  302. "must": mustMap,
  303. },
  304. },
  305. }
  306. if orderColumn == "PublishDate" {
  307. queryMap["sort"] = sortMap
  308. }
  309. queryMap["from"] = startSize
  310. queryMap["size"] = pageSize
  311. queryMap["highlight"] = highlightMap
  312. jsonBytes, _ := json.Marshal(queryMap)
  313. fmt.Println(string(jsonBytes))
  314. request := client.Search(indexName).Source(queryMap) // sets the JSON request
  315. searchByMatch, err := request.Do(context.Background())
  316. if searchByMatch != nil {
  317. if searchByMatch.Hits != nil {
  318. for _, v := range searchByMatch.Hits.Hits {
  319. var isAppend bool
  320. articleJson, err := v.Source.MarshalJSON()
  321. if err != nil {
  322. return nil, 0, err
  323. }
  324. article := new(models.CygxArticleEs)
  325. err = json.Unmarshal(articleJson, &article)
  326. if err != nil {
  327. return nil, 0, err
  328. }
  329. searchItem := new(models.SearchItem)
  330. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  331. if len(v.Highlight["BodyText"]) > 0 {
  332. searchItem.Body = v.Highlight["BodyText"]
  333. } else {
  334. bodyRune := []rune(article.BodyText)
  335. bodyRuneLen := len(bodyRune)
  336. if bodyRuneLen > 100 {
  337. bodyRuneLen = 100
  338. }
  339. body := string(bodyRune[:bodyRuneLen])
  340. searchItem.Body = []string{body}
  341. }
  342. var title string
  343. if len(v.Highlight["Title"]) > 0 {
  344. title = v.Highlight["Title"][0]
  345. } else {
  346. title = article.Title
  347. }
  348. searchItem.Title = title
  349. searchItem.PublishDate = article.PublishDate
  350. searchItem.ExpertBackground = article.ExpertBackground
  351. searchItem.CategoryId = article.CategoryId
  352. for _, v_result := range result {
  353. if v_result.ArticleId == searchItem.ArticleId {
  354. isAppend = true
  355. }
  356. }
  357. if !isAppend {
  358. result = append(result, searchItem)
  359. }
  360. }
  361. }
  362. total = searchByMatch.Hits.TotalHits.Value
  363. }
  364. return
  365. }