elastic.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. package services
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/olivere/elastic/v7"
  7. "hongze/hongze_mfyx/models"
  8. "hongze/hongze_mfyx/utils"
  9. "strconv"
  10. )
  11. func EsMultiMatchFunctionScoreQuerySort(indexName, keyWord string, startSize, pageSize, userId int, orderColumn string) (result []*models.SearchItem, total int64, err error) {
  12. client := utils.Client
  13. keyWordArr, err := GetIndustryMapNameSliceV3(keyWord)
  14. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  15. //artidArr := make([]elastic.Query, 0)
  16. //matchArr := make([]elastic.Query, 0)
  17. n := 0
  18. keyWordLen := len(keyWordArr)
  19. if keyWordLen <= 0 {
  20. keyWordArr = append(keyWordArr, keyWord)
  21. keyWordLen = len(keyWordArr)
  22. }
  23. // @Param OrderColumn query int true "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
  24. utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
  25. //keyWordWeight := GetWeight(keyWordLen)
  26. for _, v := range keyWordArr {
  27. if v != "" {
  28. matchArr := make([]elastic.Query, 0)
  29. boolquery := elastic.NewBoolQuery()
  30. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  31. bodyFunctionQuery2 := elastic.NewFunctionScoreQuery()
  32. bodyFunctionQuery3 := elastic.NewFunctionScoreQuery()
  33. //multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText").Analyzer("ik_smart")
  34. multiMatch := elastic.NewMultiMatchQuery(v, "Title").Analyzer("ik_smart").Boost(100)
  35. bodyFunctionQuery.Query(multiMatch)
  36. matchArr = append(matchArr, bodyFunctionQuery)
  37. multiMatch = elastic.NewMultiMatchQuery(v, "BodyText").Analyzer("ik_smart").Boost(1)
  38. bodyFunctionQuery2.Query(multiMatch)
  39. matchArr = append(matchArr, bodyFunctionQuery2)
  40. //multiMatch = elastic.NewMultiMatchQuery(1, "IsSummary")
  41. bodyFunctionQuery3.Query(multiMatch)
  42. matchArr = append(matchArr, bodyFunctionQuery3)
  43. boolquery.Should(matchArr...)
  44. //multiMatch = elastic.NewMultiMatchQuery(v, "BodyText").Analyzer("ik_smart")
  45. //bodyFunctionQuery.Query(multiMatch)
  46. //matchArr = append(matchArr, bodyFunctionQuery)
  47. //boolquery.Should(matchArr...)
  48. highlight := elastic.NewHighlight()
  49. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  50. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  51. request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).From(0).Size(pageSize).Query(boolquery)
  52. if orderColumn == "Matching" {
  53. request = client.Search(indexName).Highlight(highlight).From(0).Size(pageSize).Query(boolquery)
  54. }
  55. searchByMatch, err := request.Do(context.Background())
  56. if err != nil {
  57. return nil, 0, err
  58. }
  59. if searchByMatch != nil {
  60. if searchByMatch.Hits != nil {
  61. for _, v := range searchByMatch.Hits.Hits {
  62. var isAppend bool
  63. articleJson, err := v.Source.MarshalJSON()
  64. if err != nil {
  65. return nil, 0, err
  66. }
  67. article := new(models.CygxArticleEs)
  68. err = json.Unmarshal(articleJson, &article)
  69. if err != nil {
  70. return nil, 0, err
  71. }
  72. searchItem := new(models.SearchItem)
  73. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  74. if len(v.Highlight["BodyText"]) > 0 {
  75. searchItem.Body = v.Highlight["BodyText"]
  76. } else {
  77. bodyRune := []rune(article.BodyText)
  78. bodyRuneLen := len(bodyRune)
  79. if bodyRuneLen > 100 {
  80. bodyRuneLen = 100
  81. }
  82. body := string(bodyRune[:bodyRuneLen])
  83. searchItem.Body = []string{body}
  84. }
  85. var title string
  86. if len(v.Highlight["Title"]) > 0 {
  87. title = v.Highlight["Title"][0]
  88. } else {
  89. title = article.Title
  90. }
  91. searchItem.Title = title
  92. searchItem.PublishDate = article.PublishDate
  93. searchItem.ExpertBackground = article.ExpertBackground
  94. searchItem.CategoryId = article.CategoryId
  95. for _, v_result := range result {
  96. if v_result.ArticleId == searchItem.ArticleId {
  97. isAppend = true
  98. }
  99. }
  100. if !isAppend {
  101. result = append(result, searchItem)
  102. }
  103. }
  104. }
  105. //total += searchByMatch.Hits.TotalHits.Value
  106. }
  107. }
  108. n++
  109. }
  110. total = int64(len(result))
  111. return
  112. }
  113. func EsMultiMatchFunctionScoreQueryTimeSort(indexName, keyWord string, startSize, pageSize, userId int) (result []*models.SearchItem, total int64, err error) {
  114. client := utils.Client
  115. keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
  116. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  117. boolquery := elastic.NewBoolQuery()
  118. matchArr := make([]elastic.Query, 0)
  119. //matchArr2 := make([]elastic.Query, 0)
  120. n := 0
  121. keyWordLen := len(keyWordArr)
  122. if keyWordLen <= 0 {
  123. keyWordArr = append(keyWordArr, keyWord)
  124. keyWordLen = len(keyWordArr)
  125. }
  126. utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
  127. for _, v := range keyWordArr {
  128. if v != "" {
  129. multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText")
  130. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  131. bodyFunctionQuery.Query(multiMatch)
  132. matchArr = append(matchArr, bodyFunctionQuery)
  133. }
  134. n++
  135. }
  136. boolquery.Should(matchArr...)
  137. highlight := elastic.NewHighlight()
  138. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  139. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  140. request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).Size(pageSize).Query(boolquery)
  141. searchByMatch, err := request.Do(context.Background())
  142. if searchByMatch != nil {
  143. matchResult, _ := json.Marshal(searchByMatch)
  144. utils.FileLog.Info("%s", string(matchResult))
  145. fmt.Println(len(searchByMatch.Hits.Hits))
  146. if searchByMatch.Hits != nil {
  147. for _, v := range searchByMatch.Hits.Hits {
  148. articleJson, err := v.Source.MarshalJSON()
  149. utils.FileLog.Info("%s", string(articleJson))
  150. if err != nil {
  151. return nil, 0, err
  152. }
  153. article := new(models.CygxArticleEs)
  154. err = json.Unmarshal(articleJson, &article)
  155. if err != nil {
  156. return nil, 0, err
  157. }
  158. searchItem := new(models.SearchItem)
  159. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  160. if len(v.Highlight["BodyText"]) > 0 {
  161. searchItem.Body = v.Highlight["BodyText"]
  162. } else {
  163. bodyRune := []rune(article.BodyText)
  164. bodyRuneLen := len(bodyRune)
  165. if bodyRuneLen > 100 {
  166. bodyRuneLen = 100
  167. }
  168. body := string(bodyRune[:bodyRuneLen])
  169. searchItem.Body = []string{body}
  170. }
  171. var title string
  172. if len(v.Highlight["Title"]) > 0 {
  173. title = v.Highlight["Title"][0]
  174. } else {
  175. title = article.Title
  176. }
  177. searchItem.Title = title
  178. searchItem.PublishDate = article.PublishDate
  179. searchItem.ExpertBackground = article.ExpertBackground
  180. searchItem.CategoryId = article.CategoryId
  181. result = append(result, searchItem)
  182. }
  183. }
  184. total = searchByMatch.Hits.TotalHits.Value
  185. }
  186. return
  187. }
  188. func EsSearchReport(indexName, keyWord string, startSize, pageSize, userId int) (result []*models.SearchItem, total int64, err error) {
  189. client := utils.Client
  190. keyWordArr, err := GetIndustryMapNameSliceV3(keyWord)
  191. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  192. n := 0
  193. keyWordLen := len(keyWordArr)
  194. if keyWordLen <= 0 {
  195. keyWordArr = append(keyWordArr, keyWord)
  196. keyWordLen = len(keyWordArr)
  197. }
  198. for _, v := range keyWordArr {
  199. fmt.Println(v)
  200. }
  201. utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
  202. for _, v := range keyWordArr {
  203. if v != "" {
  204. matchArr := make([]elastic.Query, 0)
  205. boolquery := elastic.NewBoolQuery()
  206. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  207. bodyFunctionQuery2 := elastic.NewFunctionScoreQuery()
  208. multiMatch := elastic.NewMultiMatchQuery(v, "Title").Analyzer("ik_smart")
  209. bodyFunctionQuery.Query(multiMatch)
  210. matchArr = append(matchArr, bodyFunctionQuery)
  211. multiMatch = elastic.NewMultiMatchQuery(1, "IsReport")
  212. bodyFunctionQuery2.Query(multiMatch)
  213. matchArr = append(matchArr, bodyFunctionQuery2)
  214. boolquery.Must(matchArr...)
  215. highlight := elastic.NewHighlight()
  216. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  217. highlight = highlight.Fields(elastic.NewHighlighterField("Title"))
  218. request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).From(0).Size(pageSize).Query(boolquery)
  219. searchByMatch, err := request.Do(context.Background())
  220. if err != nil {
  221. return nil, 0, err
  222. }
  223. if searchByMatch != nil {
  224. if searchByMatch.Hits != nil {
  225. for _, v := range searchByMatch.Hits.Hits {
  226. var isAppend bool
  227. articleJson, err := v.Source.MarshalJSON()
  228. if err != nil {
  229. return nil, 0, err
  230. }
  231. article := new(models.CygxArticleEs)
  232. err = json.Unmarshal(articleJson, &article)
  233. if err != nil {
  234. return nil, 0, err
  235. }
  236. searchItem := new(models.SearchItem)
  237. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  238. var title string
  239. if len(v.Highlight["Title"]) > 0 {
  240. title = v.Highlight["Title"][0]
  241. } else {
  242. title = article.Title
  243. }
  244. searchItem.Title = title
  245. searchItem.PublishDate = article.PublishDate
  246. for _, v_result := range result {
  247. if v_result.ArticleId == searchItem.ArticleId {
  248. isAppend = true
  249. }
  250. }
  251. if !isAppend {
  252. result = append(result, searchItem)
  253. }
  254. }
  255. }
  256. }
  257. }
  258. n++
  259. }
  260. total = int64(len(result))
  261. return
  262. }
  263. func EsArticleSearch(keyWord string, startSize, pageSize int, orderColumn string, ikType int) (result []*models.SearchItem, total int64, err error) {
  264. indexName := utils.IndexName
  265. client := utils.Client
  266. keyWordArr, err := GetIndustryMapNameSliceV3(keyWord)
  267. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  268. keyWordLen := len(keyWordArr)
  269. if keyWordLen <= 0 {
  270. keyWordArr = append(keyWordArr, keyWord)
  271. keyWordLen = len(keyWordArr)
  272. }
  273. fmt.Println(keyWordArr)
  274. //如果没有联想词,而且查询的还是联想词就返回
  275. if ikType == 2 && keyWordLen == 1 {
  276. return
  277. }
  278. //Es 的高级查询有 自定义排序 文档一时半会儿撸不懂,先做多次查询手动过滤 2023.2.2
  279. //ikType 查询方式 ,0:查所有 、 1:查询键入词 、 2:查询除了查询键入词之外的联想词
  280. mustMap := make([]interface{}, 0)
  281. shouldMap := make(map[string]interface{}, 0)
  282. shouldMapquery := make([]interface{}, 0)
  283. mustNotMap := make([]interface{}, 0)
  284. shouldNotMap := make(map[string]interface{}, 0)
  285. shouldNotMapquery := make([]interface{}, 0)
  286. // @Param OrderColumn query int true "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
  287. //keyWordWeight := GetWeight(keyWordLen)
  288. var boost int
  289. //lenkeyWordArr := len(keyWordArr)
  290. for k, v := range keyWordArr {
  291. if k == 0 {
  292. boost = 2 * 1000
  293. } else {
  294. boost = 1
  295. }
  296. //如果是 2:查询除了查询键入词之外的联想词
  297. if k == 0 && ikType == 2 {
  298. if v != "" {
  299. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  300. "function_score": map[string]interface{}{
  301. "query": map[string]interface{}{
  302. "multi_match": map[string]interface{}{
  303. //"boost": (lenkeyWordArr - k) * boost, //给查询的值赋予权重
  304. "boost": boost, //给查询的值赋予权重
  305. "fields": []interface{}{"Title"},
  306. "query": v,
  307. },
  308. },
  309. },
  310. })
  311. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  312. "function_score": map[string]interface{}{
  313. "query": map[string]interface{}{
  314. "multi_match": map[string]interface{}{
  315. "boost": boost, //给查询的值赋予权重
  316. "fields": []interface{}{"Abstract"},
  317. "query": v,
  318. },
  319. },
  320. },
  321. })
  322. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  323. "function_score": map[string]interface{}{
  324. "query": map[string]interface{}{
  325. "multi_match": map[string]interface{}{
  326. "boost": boost, //给查询的值赋予权重
  327. "fields": []interface{}{"Annotation"},
  328. "query": v,
  329. },
  330. },
  331. },
  332. })
  333. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  334. "function_score": map[string]interface{}{
  335. "query": map[string]interface{}{
  336. "multi_match": map[string]interface{}{
  337. //"boost": (lenkeyWordArr-k)*boost - 1, //给查询的值赋予权重
  338. "boost": boost, //给查询的值赋予权重
  339. "fields": []interface{}{"BodyText"},
  340. "query": v,
  341. },
  342. },
  343. },
  344. })
  345. }
  346. continue
  347. }
  348. //如果是 1:查询键入词
  349. if k > 0 && ikType == 1 {
  350. continue
  351. }
  352. if v != "" {
  353. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  354. "function_score": map[string]interface{}{
  355. "query": map[string]interface{}{
  356. "multi_match": map[string]interface{}{
  357. //"boost": (lenkeyWordArr - k) * boost, //给查询的值赋予权重
  358. "boost": boost, //给查询的值赋予权重
  359. "fields": []interface{}{"Title"},
  360. "query": v,
  361. },
  362. },
  363. },
  364. })
  365. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  366. "function_score": map[string]interface{}{
  367. "query": map[string]interface{}{
  368. "multi_match": map[string]interface{}{
  369. "boost": boost, //给查询的值赋予权重
  370. "fields": []interface{}{"Abstract"},
  371. "query": v,
  372. },
  373. },
  374. },
  375. })
  376. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  377. "function_score": map[string]interface{}{
  378. "query": map[string]interface{}{
  379. "multi_match": map[string]interface{}{
  380. "boost": boost, //给查询的值赋予权重
  381. "fields": []interface{}{"Annotation"},
  382. "query": v,
  383. },
  384. },
  385. },
  386. })
  387. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  388. "function_score": map[string]interface{}{
  389. "query": map[string]interface{}{
  390. "multi_match": map[string]interface{}{
  391. //"boost": (lenkeyWordArr-k)*boost - 1, //给查询的值赋予权重
  392. "boost": boost, //给查询的值赋予权重
  393. "fields": []interface{}{"BodyText"},
  394. "query": v,
  395. },
  396. },
  397. },
  398. })
  399. }
  400. }
  401. shouldMap = map[string]interface{}{
  402. "should": shouldMapquery,
  403. }
  404. shouldNotMap = map[string]interface{}{
  405. "should": shouldNotMapquery,
  406. }
  407. //排序
  408. sortMap := make([]interface{}, 0)
  409. //时间
  410. sortMap = append(sortMap, map[string]interface{}{
  411. "PublishDate": map[string]interface{}{
  412. "order": "desc",
  413. },
  414. })
  415. //sortMap = append(sortMap, map[string]interface{}{
  416. // "_score": map[string]interface{}{
  417. // "order": "desc",
  418. // },
  419. //})
  420. //高亮
  421. highlightMap := make(map[string]interface{}, 0)
  422. highlightMap = map[string]interface{}{
  423. "fields": map[string]interface{}{
  424. "BodyText": map[string]interface{}{},
  425. "Title": map[string]interface{}{},
  426. "Abstract": map[string]interface{}{},
  427. "Annotation": map[string]interface{}{},
  428. },
  429. //样式 红色
  430. "post_tags": []interface{}{"</font>"},
  431. "pre_tags": []interface{}{"<font color='red'>"},
  432. "fragment_size": 50,
  433. }
  434. mustMap = append(mustMap, map[string]interface{}{
  435. "bool": shouldMap,
  436. })
  437. mustNotMap = append(mustNotMap, map[string]interface{}{
  438. "bool": shouldNotMap,
  439. })
  440. queryMap := map[string]interface{}{
  441. "query": map[string]interface{}{
  442. "bool": map[string]interface{}{
  443. "must": mustMap,
  444. },
  445. },
  446. }
  447. //把第一次键入词的筛选条件过滤掉
  448. if ikType == 2 {
  449. queryMap = map[string]interface{}{
  450. "query": map[string]interface{}{
  451. "bool": map[string]interface{}{
  452. "must": mustMap,
  453. "must_not": mustNotMap,
  454. },
  455. },
  456. }
  457. }
  458. if orderColumn == "Matching" {
  459. queryMap["sort"] = sortMap
  460. }
  461. queryMap["from"] = startSize
  462. queryMap["size"] = pageSize
  463. queryMap["highlight"] = highlightMap
  464. jsonBytes, _ := json.Marshal(queryMap)
  465. fmt.Println(string(jsonBytes))
  466. //utils.FileLog.Info(string(jsonBytes))
  467. request := client.Search(indexName).Source(queryMap) // sets the JSON request
  468. searchByMatch, err := request.Do(context.Background())
  469. if searchByMatch != nil {
  470. if searchByMatch.Hits != nil {
  471. for _, v := range searchByMatch.Hits.Hits {
  472. var isAppend bool
  473. articleJson, err := v.Source.MarshalJSON()
  474. if err != nil {
  475. return nil, 0, err
  476. }
  477. article := new(models.CygxArticleEs)
  478. err = json.Unmarshal(articleJson, &article)
  479. if err != nil {
  480. return nil, 0, err
  481. }
  482. searchItem := new(models.SearchItem)
  483. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  484. if len(v.Highlight["Annotation"]) > 0 {
  485. for _, vText := range v.Highlight["Annotation"] {
  486. searchItem.Body = append(searchItem.Body, vText)
  487. }
  488. }
  489. if len(v.Highlight["Abstract"]) > 0 {
  490. for _, vText := range v.Highlight["Abstract"] {
  491. searchItem.Body = append(searchItem.Body, vText)
  492. }
  493. }
  494. if len(v.Highlight["BodyText"]) > 0 {
  495. for _, vText := range v.Highlight["BodyText"] {
  496. searchItem.Body = append(searchItem.Body, vText)
  497. }
  498. }
  499. if len(searchItem.Body) == 0 {
  500. bodyRune := []rune(article.BodyText)
  501. bodyRuneLen := len(bodyRune)
  502. if bodyRuneLen > 100 {
  503. bodyRuneLen = 100
  504. }
  505. body := string(bodyRune[:bodyRuneLen])
  506. searchItem.Body = []string{body}
  507. }
  508. //if len(v.Highlight["BodyText"]) > 0 {
  509. // searchItem.Body = v.Highlight["BodyText"]
  510. //} else {
  511. // bodyRune := []rune(article.BodyText)
  512. // bodyRuneLen := len(bodyRune)
  513. // if bodyRuneLen > 100 {
  514. // bodyRuneLen = 100
  515. // }
  516. // body := string(bodyRune[:bodyRuneLen])
  517. // searchItem.Body = []string{body}
  518. //}
  519. var title string
  520. if len(v.Highlight["Title"]) > 0 {
  521. title = v.Highlight["Title"][0]
  522. } else {
  523. title = article.Title
  524. }
  525. searchItem.Title = title
  526. searchItem.PublishDate = article.PublishDate
  527. searchItem.ExpertBackground = article.ExpertBackground
  528. searchItem.CategoryId = article.CategoryId
  529. for _, v_result := range result {
  530. if v_result.ArticleId == searchItem.ArticleId {
  531. isAppend = true
  532. }
  533. }
  534. if !isAppend {
  535. result = append(result, searchItem)
  536. }
  537. }
  538. }
  539. total = searchByMatch.Hits.TotalHits.Value
  540. }
  541. return
  542. }
  543. func EsArticleSearchBody(keyWord string, startSize, pageSize int, orderColumn string, searchType int) (result []*models.SearchItem, total int64, err error) {
  544. if keyWord == "" {
  545. return
  546. }
  547. indexName := utils.IndexName
  548. client := utils.Client
  549. //Es 的高级查询有 自定义排序 文档一时半会儿撸不懂,先做多次查询手动过滤 2023.2.2
  550. //ikType 查询方式 ,0:查所有 、 1:查询键入词 、 2:查询除了查询键入词之外的联想词
  551. mustMap := make([]interface{}, 0)
  552. shouldMap := make(map[string]interface{}, 0)
  553. shouldMapquery := make([]interface{}, 0)
  554. mustNotMap := make([]interface{}, 0)
  555. shouldNotMap := make(map[string]interface{}, 0)
  556. shouldNotMapquery := make([]interface{}, 0)
  557. // @Param OrderColumn query int true "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
  558. //keyWordWeight := GetWeight(keyWordLen)
  559. var boost int
  560. //如果是 2:查询标题,摘要,核心观点的词
  561. if searchType == 1 {
  562. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  563. "function_score": map[string]interface{}{
  564. "query": map[string]interface{}{
  565. "multi_match": map[string]interface{}{
  566. "boost": boost, //给查询的值赋予权重
  567. "fields": []interface{}{"Title"},
  568. "query": keyWord,
  569. },
  570. },
  571. },
  572. })
  573. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  574. "function_score": map[string]interface{}{
  575. "query": map[string]interface{}{
  576. "multi_match": map[string]interface{}{
  577. "boost": boost, //给查询的值赋予权重
  578. "fields": []interface{}{"Abstract"},
  579. "query": keyWord,
  580. },
  581. },
  582. },
  583. })
  584. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  585. "function_score": map[string]interface{}{
  586. "query": map[string]interface{}{
  587. "multi_match": map[string]interface{}{
  588. "boost": boost, //给查询的值赋予权重
  589. "fields": []interface{}{"Annotation"},
  590. "query": keyWord,
  591. },
  592. },
  593. },
  594. })
  595. }
  596. //如果是 2:查询body的相关词
  597. if searchType == 2 {
  598. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  599. "function_score": map[string]interface{}{
  600. "query": map[string]interface{}{
  601. "multi_match": map[string]interface{}{
  602. "boost": boost, //给查询的值赋予权重
  603. "fields": []interface{}{"Title"},
  604. "query": keyWord,
  605. },
  606. },
  607. },
  608. })
  609. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  610. "function_score": map[string]interface{}{
  611. "query": map[string]interface{}{
  612. "multi_match": map[string]interface{}{
  613. "boost": boost, //给查询的值赋予权重
  614. "fields": []interface{}{"Abstract"},
  615. "query": keyWord,
  616. },
  617. },
  618. },
  619. })
  620. shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  621. "function_score": map[string]interface{}{
  622. "query": map[string]interface{}{
  623. "multi_match": map[string]interface{}{
  624. "boost": boost, //给查询的值赋予权重
  625. "fields": []interface{}{"Annotation"},
  626. "query": keyWord,
  627. },
  628. },
  629. },
  630. })
  631. //shouldNotMapquery = append(shouldNotMapquery, map[string]interface{}{
  632. // "function_score": map[string]interface{}{
  633. // "query": map[string]interface{}{
  634. // "multi_match": map[string]interface{}{
  635. // //"boost": (lenkeyWordArr-k)*boost - 1, //给查询的值赋予权重
  636. // "boost": boost, //给查询的值赋予权重
  637. // "fields": []interface{}{"BodyText"},
  638. // "query": keyWord,
  639. // },
  640. // },
  641. // },
  642. //})
  643. shouldMapquery = append(shouldMapquery, map[string]interface{}{
  644. "function_score": map[string]interface{}{
  645. "query": map[string]interface{}{
  646. "multi_match": map[string]interface{}{
  647. //"boost": (lenkeyWordArr-k)*boost - 1, //给查询的值赋予权重
  648. "boost": boost, //给查询的值赋予权重
  649. "fields": []interface{}{"BodyText"},
  650. "query": keyWord,
  651. },
  652. },
  653. },
  654. })
  655. }
  656. shouldMap = map[string]interface{}{
  657. "should": shouldMapquery,
  658. }
  659. shouldNotMap = map[string]interface{}{
  660. "should": shouldNotMapquery,
  661. }
  662. //排序
  663. sortMap := make([]interface{}, 0)
  664. //时间
  665. sortMap = append(sortMap, map[string]interface{}{
  666. "PublishDate": map[string]interface{}{
  667. "order": "desc",
  668. },
  669. })
  670. //高亮
  671. highlightMap := make(map[string]interface{}, 0)
  672. highlightMap = map[string]interface{}{
  673. "fields": map[string]interface{}{
  674. "BodyText": map[string]interface{}{},
  675. "Title": map[string]interface{}{},
  676. "Abstract": map[string]interface{}{},
  677. "Annotation": map[string]interface{}{},
  678. },
  679. //样式 红色
  680. "post_tags": []interface{}{"</font>"},
  681. "pre_tags": []interface{}{"<font color='red'>"},
  682. "fragment_size": 50,
  683. }
  684. mustMap = append(mustMap, map[string]interface{}{
  685. "bool": shouldMap,
  686. })
  687. mustNotMap = append(mustNotMap, map[string]interface{}{
  688. "bool": shouldNotMap,
  689. })
  690. queryMap := map[string]interface{}{
  691. "query": map[string]interface{}{
  692. "bool": map[string]interface{}{
  693. "must": mustMap,
  694. },
  695. },
  696. }
  697. //把第一次的筛选条件过滤掉
  698. if searchType == 2 {
  699. queryMap = map[string]interface{}{
  700. "query": map[string]interface{}{
  701. "bool": map[string]interface{}{
  702. "must": mustMap,
  703. "must_not": mustNotMap,
  704. },
  705. },
  706. }
  707. }
  708. if orderColumn == "Matching" {
  709. queryMap["sort"] = sortMap
  710. }
  711. queryMap["from"] = startSize
  712. queryMap["size"] = pageSize
  713. queryMap["highlight"] = highlightMap
  714. jsonBytes, _ := json.Marshal(queryMap)
  715. fmt.Println(string(jsonBytes))
  716. //utils.FileLog.Info(string(jsonBytes))
  717. request := client.Search(indexName).Source(queryMap) // sets the JSON request
  718. searchByMatch, err := request.Do(context.Background())
  719. if searchByMatch != nil {
  720. if searchByMatch.Hits != nil {
  721. for _, v := range searchByMatch.Hits.Hits {
  722. var isAppend bool
  723. articleJson, err := v.Source.MarshalJSON()
  724. if err != nil {
  725. return nil, 0, err
  726. }
  727. article := new(models.CygxArticleEs)
  728. err = json.Unmarshal(articleJson, &article)
  729. if err != nil {
  730. return nil, 0, err
  731. }
  732. searchItem := new(models.SearchItem)
  733. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  734. if len(v.Highlight["Annotation"]) > 0 {
  735. for _, vText := range v.Highlight["Annotation"] {
  736. searchItem.Body = append(searchItem.Body, vText)
  737. }
  738. }
  739. if len(v.Highlight["Abstract"]) > 0 {
  740. for _, vText := range v.Highlight["Abstract"] {
  741. searchItem.Body = append(searchItem.Body, vText)
  742. }
  743. }
  744. if len(v.Highlight["BodyText"]) > 0 {
  745. for _, vText := range v.Highlight["BodyText"] {
  746. searchItem.Body = append(searchItem.Body, vText)
  747. }
  748. }
  749. if len(searchItem.Body) == 0 {
  750. bodyRune := []rune(article.BodyText)
  751. bodyRuneLen := len(bodyRune)
  752. if bodyRuneLen > 100 {
  753. bodyRuneLen = 100
  754. }
  755. body := string(bodyRune[:bodyRuneLen])
  756. searchItem.Body = []string{body}
  757. }
  758. //if len(v.Highlight["BodyText"]) > 0 {
  759. // searchItem.Body = v.Highlight["BodyText"]
  760. //} else {
  761. // bodyRune := []rune(article.BodyText)
  762. // bodyRuneLen := len(bodyRune)
  763. // if bodyRuneLen > 100 {
  764. // bodyRuneLen = 100
  765. // }
  766. // body := string(bodyRune[:bodyRuneLen])
  767. // searchItem.Body = []string{body}
  768. //}
  769. var title string
  770. if len(v.Highlight["Title"]) > 0 {
  771. title = v.Highlight["Title"][0]
  772. } else {
  773. title = article.Title
  774. }
  775. searchItem.Title = title
  776. searchItem.PublishDate = article.PublishDate
  777. searchItem.ExpertBackground = article.ExpertBackground
  778. searchItem.CategoryId = article.CategoryId
  779. for _, v_result := range result {
  780. if v_result.ArticleId == searchItem.ArticleId {
  781. isAppend = true
  782. }
  783. }
  784. if !isAppend {
  785. result = append(result, searchItem)
  786. }
  787. }
  788. }
  789. total = searchByMatch.Hits.TotalHits.Value
  790. }
  791. return
  792. }