elastic.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. package services
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/olivere/elastic/v7"
  7. "hongze/hongze_cygx/models"
  8. "hongze/hongze_cygx/utils"
  9. "log"
  10. "os"
  11. "sort"
  12. "strconv"
  13. )
  14. func NewClient() (client *elastic.Client, err error) {
  15. errorlog := log.New(os.Stdout, "APP", log.LstdFlags)
  16. file := "./rdlucklog/eslog.log"
  17. logFile, _ := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
  18. client, err = elastic.NewClient(
  19. elastic.SetURL(ES_URL),
  20. elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
  21. elastic.SetTraceLog(log.New(logFile, "ES-TRACE: ", 0)),
  22. elastic.SetSniff(false), elastic.SetErrorLog(errorlog))
  23. return
  24. }
  25. //indexName:索引名称
  26. //mappingJson:表结构
  27. func EsCreateIndex(indexName, mappingJson string) (err error) {
  28. client, err := NewClient()
  29. if err != nil {
  30. return
  31. }
  32. //定义表结构
  33. exists, err := client.IndexExists(indexName).Do(context.Background()) //<5>
  34. if err != nil {
  35. return
  36. }
  37. if !exists {
  38. resp, err := client.CreateIndex(indexName).BodyJson(mappingJson).Do(context.Background())
  39. //BodyJson(bodyJson).Do(context.Background())
  40. if err != nil {
  41. fmt.Println("CreateIndex Err:" + err.Error())
  42. return err
  43. }
  44. fmt.Println(resp.Index, resp.ShardsAcknowledged, resp.Acknowledged)
  45. } else {
  46. fmt.Println(indexName + " 已存在")
  47. }
  48. return
  49. }
  50. //新增数据
  51. func EsAddOrEditData(indexName, docId string, item *ElasticArticleDetail) (err error) {
  52. defer func() {
  53. if err != nil {
  54. fmt.Println("EsAddOrEditData Err:", err.Error())
  55. }
  56. }()
  57. client, err := NewClient()
  58. if err != nil {
  59. return
  60. }
  61. searchById, err := client.Get().Index(indexName).Id(docId).Do(context.Background())
  62. if err != nil {
  63. return
  64. }
  65. if searchById.Found {
  66. resp, err := client.Update().Index(indexName).Id(docId).Doc(map[string]interface{}{
  67. "BodyText": item.BodyText,
  68. "Title": item.Title,
  69. }).Do(context.Background())
  70. if err != nil {
  71. return err
  72. }
  73. fmt.Println(resp.Status, resp.Result)
  74. if resp.Status == 0 {
  75. fmt.Println("修改成功")
  76. } else {
  77. fmt.Println("EditData", resp.Status, resp.Result)
  78. }
  79. } else {
  80. resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
  81. if err != nil {
  82. return err
  83. }
  84. if resp.Status == 0 && resp.Result == "created" {
  85. fmt.Println("新增成功")
  86. } else {
  87. fmt.Println("AddData", resp.Status, resp.Result)
  88. }
  89. }
  90. return
  91. }
  92. //删除数据
  93. func EsDeleteData(indexName, docId string) (err error) {
  94. client, err := NewClient()
  95. if err != nil {
  96. return
  97. }
  98. resp, err := client.Delete().Index(indexName).Id(docId).Do(context.Background())
  99. if err != nil {
  100. return
  101. }
  102. if resp.Status == 0 {
  103. fmt.Println("删除成功")
  104. } else {
  105. fmt.Println("AddData", resp.Status, resp.Result)
  106. }
  107. return
  108. }
  109. func MappingModify(indexName, mappingJson string) {
  110. client, err := NewClient()
  111. if err != nil {
  112. return
  113. }
  114. result, err := client.PutMapping().Index(indexName).BodyString(mappingJson).Do(context.Background())
  115. fmt.Println(err)
  116. fmt.Println(result)
  117. return
  118. }
  119. func EsMatchQuery(indexName, keyWord string) (result []*models.SearchItem, err error) {
  120. client, err := NewClient()
  121. pageSize := 20
  122. keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
  123. fmt.Println(keyWordArr)
  124. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  125. fmt.Println("-------------------------------")
  126. fmt.Println(keyWordArr)
  127. searchMap := make(map[int]int)
  128. boolquery := elastic.NewBoolQuery()
  129. keyLen := len(keyWordArr)
  130. n := 5.0 * float64(keyLen)
  131. matchArr := make([]elastic.Query, 0)
  132. //
  133. //matchq1 := elastic.NewMatchQuery("Title", keyWord).Boost(n + 1).Analyzer("ik_smart")
  134. //matchq2 := elastic.NewMatchQuery("BodyText", keyWord).Boost(n + 1).Analyzer("ik_smart")
  135. //
  136. //matchArr = append(matchArr, matchq1)
  137. //matchArr = append(matchArr, matchq2)
  138. for _, v := range keyWordArr {
  139. if v != "" {
  140. matchq1 := elastic.NewMatchQuery("Title", v).Boost(n).Analyzer("ik_smart")
  141. matchq2 := elastic.NewMatchQuery("BodyText", v).Boost(n).Analyzer("ik_smart")
  142. matchArr = append(matchArr, matchq1)
  143. matchArr = append(matchArr, matchq2)
  144. }
  145. n = n - 5
  146. }
  147. boolquery.Should(matchArr...)
  148. highlight := elastic.NewHighlight()
  149. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  150. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  151. request := client.Search(indexName).Highlight(highlight).Size(pageSize).Query(boolquery)
  152. searchByMatch, err := request.Do(context.Background())
  153. if searchByMatch.Hits != nil {
  154. for _, v := range searchByMatch.Hits.Hits {
  155. articleJson, err := v.Source.MarshalJSON()
  156. if err != nil {
  157. return nil, err
  158. }
  159. article := new(models.CygxArticle)
  160. err = json.Unmarshal(articleJson, &article)
  161. if err != nil {
  162. return nil, err
  163. }
  164. if _, ok := searchMap[article.ArticleId]; !ok {
  165. searchItem := new(models.SearchItem)
  166. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  167. if len(v.Highlight["BodyText"]) > 0 {
  168. searchItem.Body = v.Highlight["BodyText"]
  169. } else {
  170. bodyRune := []rune(article.BodyText)
  171. bodyRuneLen := len(bodyRune)
  172. if bodyRuneLen > 100 {
  173. bodyRuneLen = 100
  174. }
  175. body := string(bodyRune[:bodyRuneLen])
  176. fmt.Println(body)
  177. searchItem.Body = []string{body}
  178. }
  179. var title string
  180. if len(v.Highlight["Title"]) > 0 {
  181. title = v.Highlight["Title"][0]
  182. } else {
  183. title = article.Title
  184. }
  185. searchItem.Title = title
  186. searchItem.PublishDate = article.PublishDate
  187. result = append(result, searchItem)
  188. searchMap[article.ArticleId] = article.ArticleId
  189. }
  190. }
  191. }
  192. return
  193. }
  194. func EsMatchPhraseQuery(indexName, keyWord string) (result []*models.SearchItem, err error) {
  195. client, err := NewClient()
  196. pageSize := 20
  197. keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
  198. fmt.Println(keyWordArr)
  199. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  200. fmt.Println("-------------------------------")
  201. fmt.Println(keyWordArr)
  202. searchMap := make(map[int]int)
  203. boolquery := elastic.NewBoolQuery()
  204. //keyLen := len(keyWordArr)
  205. //n := float64(keyLen)
  206. matchArr := make([]elastic.Query, 0)
  207. //matchq1 := elastic.NewMatchQuery("Title", keyWord).Boost(n + 1).Analyzer("ik_smart")
  208. //matchq2 := elastic.NewMatchQuery("BodyText", keyWord).Boost(n + 1).Analyzer("ik_smart")
  209. matchq1 := elastic.NewMatchPhraseQuery("Title", keyWord) //.Analyzer("ik_smart")
  210. matchq2 := elastic.NewMatchPhraseQuery("BodyText", keyWord)
  211. matchArr = append(matchArr, matchq1)
  212. matchArr = append(matchArr, matchq2)
  213. //matchArr = append(matchArr, matchq2)
  214. //for _, v := range keyWordArr {
  215. // if v != "" {
  216. // matchq1 := elastic.NewMatchQuery("Title", v).Boost(n).Analyzer("ik_smart")
  217. // matchq2 := elastic.NewMatchQuery("BodyText", v).Boost(n).Analyzer("ik_smart")
  218. // matchArr = append(matchArr, matchq1)
  219. // matchArr = append(matchArr, matchq2)
  220. // }
  221. // n--
  222. //}
  223. //boolquery.Should(matchArr...)
  224. boolquery.Should(matchArr...)
  225. highlight := elastic.NewHighlight()
  226. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  227. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  228. request := client.Search(indexName).Highlight(highlight).Size(pageSize).Query(boolquery)
  229. searchByMatch, err := request.Do(context.Background())
  230. fmt.Println("err:", err, searchByMatch)
  231. return
  232. if searchByMatch.Hits != nil {
  233. for _, v := range searchByMatch.Hits.Hits {
  234. articleJson, err := v.Source.MarshalJSON()
  235. if err != nil {
  236. return nil, err
  237. }
  238. article := new(models.CygxArticle)
  239. err = json.Unmarshal(articleJson, &article)
  240. if err != nil {
  241. return nil, err
  242. }
  243. if _, ok := searchMap[article.ArticleId]; !ok {
  244. searchItem := new(models.SearchItem)
  245. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  246. searchItem.Body = v.Highlight["BodyText"]
  247. var title string
  248. if len(v.Highlight["Title"]) > 0 {
  249. title = v.Highlight["Title"][0]
  250. } else {
  251. title = article.Title
  252. }
  253. searchItem.Title = title
  254. searchItem.PublishDate = article.PublishDate
  255. result = append(result, searchItem)
  256. searchMap[article.ArticleId] = article.ArticleId
  257. }
  258. }
  259. }
  260. return
  261. }
  262. func EsMatchFunctionScoreQuery(indexName, keyWord string, startSize, pageSize int) (result []*models.SearchItem, total int64, err error) {
  263. client, err := NewClient()
  264. keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
  265. fmt.Println(keyWordArr)
  266. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  267. fmt.Println("-------------------------------")
  268. fmt.Println(keyWordArr)
  269. searchMap := make(map[int]int)
  270. boolquery := elastic.NewBoolQuery()
  271. matchArr := make([]elastic.Query, 0)
  272. //
  273. //matchq1 := elastic.NewMatchQuery("Title", keyWord).Boost(n + 1).Analyzer("ik_smart")
  274. //matchq2 := elastic.NewMatchQuery("BodyText", keyWord).Boost(n + 1).Analyzer("ik_smart")
  275. //
  276. //matchArr = append(matchArr, matchq1)
  277. //matchArr = append(matchArr, matchq2)
  278. n := 0
  279. keyWordLen := len(keyWordArr)
  280. if keyWordLen <= 0 {
  281. keyWordArr = append(keyWordArr, keyWord)
  282. keyWordLen = len(keyWordArr)
  283. }
  284. keyWordWeight := GetWeight(keyWordLen)
  285. fmt.Println(keyWordArr)
  286. fmt.Println(keyWordWeight)
  287. for k, v := range keyWordArr {
  288. if v != "" {
  289. weight := float64(keyWordWeight[k])
  290. titleMatchq := elastic.NewMatchQuery("Title", v).Analyzer("ik_smart")
  291. bodyMatchq := elastic.NewMatchQuery("BodyText", v).Analyzer("ik_smart")
  292. titleFunctionQuery := elastic.NewFunctionScoreQuery()
  293. titleFunctionQuery.Query(titleMatchq)
  294. titleFunctions := elastic.NewWeightFactorFunction(weight)
  295. titleFunctionQuery.AddScoreFunc(titleFunctions)
  296. titleFunctionQuery.BoostMode("replace")
  297. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  298. bodyFunctionQuery.Query(bodyMatchq)
  299. bodyFunctions := elastic.NewWeightFactorFunction(weight)
  300. bodyFunctionQuery.AddScoreFunc(bodyFunctions)
  301. bodyFunctionQuery.BoostMode("replace")
  302. matchArr = append(matchArr, titleFunctionQuery)
  303. matchArr = append(matchArr, bodyFunctionQuery)
  304. }
  305. n++
  306. }
  307. boolquery.Should(matchArr...)
  308. highlight := elastic.NewHighlight()
  309. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  310. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  311. request := client.Search(indexName).Highlight(highlight).From(startSize).Size(pageSize).Query(boolquery)
  312. searchByMatch, err := request.Do(context.Background())
  313. searchJson, err := json.Marshal(searchByMatch)
  314. utils.FileLog.Info("%s", string(searchJson))
  315. if searchByMatch != nil {
  316. if searchByMatch.Hits != nil {
  317. for _, v := range searchByMatch.Hits.Hits {
  318. articleJson, err := v.Source.MarshalJSON()
  319. if err != nil {
  320. return nil, 0, err
  321. }
  322. article := new(models.CygxArticle)
  323. err = json.Unmarshal(articleJson, &article)
  324. if err != nil {
  325. return nil, 0, err
  326. }
  327. if _, ok := searchMap[article.ArticleId]; !ok {
  328. searchItem := new(models.SearchItem)
  329. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  330. if len(v.Highlight["BodyText"]) > 0 {
  331. searchItem.Body = v.Highlight["BodyText"]
  332. } else {
  333. bodyRune := []rune(article.BodyText)
  334. bodyRuneLen := len(bodyRune)
  335. if bodyRuneLen > 100 {
  336. bodyRuneLen = 100
  337. }
  338. body := string(bodyRune[:bodyRuneLen])
  339. fmt.Println(body)
  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. result = append(result, searchItem)
  351. searchMap[article.ArticleId] = article.ArticleId
  352. }
  353. }
  354. }
  355. }
  356. total = searchByMatch.Hits.TotalHits.Value
  357. return
  358. }
  359. func EsMultiMatchFunctionScoreQuery(indexName, keyWord string, startSize, pageSize int) (result []*models.SearchItem, total int64, err error) {
  360. client, err := NewClient()
  361. keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
  362. keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
  363. searchMap := make(map[int]int)
  364. boolquery := elastic.NewBoolQuery()
  365. matchArr := make([]elastic.Query, 0)
  366. n := 0
  367. keyWordLen := len(keyWordArr)
  368. if keyWordLen <= 0 {
  369. keyWordArr = append(keyWordArr, keyWord)
  370. keyWordLen = len(keyWordArr)
  371. }
  372. keyWordWeight := GetWeight(keyWordLen)
  373. for k, v := range keyWordArr {
  374. if v != "" {
  375. weight := float64(keyWordWeight[k])
  376. multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText").Analyzer("ik_smart")
  377. bodyFunctionQuery := elastic.NewFunctionScoreQuery()
  378. bodyFunctionQuery.Query(multiMatch)
  379. bodyFunctions := elastic.NewWeightFactorFunction(weight)
  380. bodyFunctionQuery.AddScoreFunc(bodyFunctions)
  381. bodyFunctionQuery.BoostMode("replace")
  382. matchArr = append(matchArr, bodyFunctionQuery)
  383. }
  384. n++
  385. }
  386. boolquery.Should(matchArr...)
  387. highlight := elastic.NewHighlight()
  388. highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
  389. highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
  390. request := client.Search(indexName).Highlight(highlight).From(startSize).Size(pageSize).Query(boolquery)
  391. searchByMatch, err := request.Do(context.Background())
  392. if searchByMatch != nil {
  393. if searchByMatch.Hits != nil {
  394. for _, v := range searchByMatch.Hits.Hits {
  395. articleJson, err := v.Source.MarshalJSON()
  396. if err != nil {
  397. return nil, 0, err
  398. }
  399. article := new(models.CygxArticle)
  400. err = json.Unmarshal(articleJson, &article)
  401. if err != nil {
  402. return nil, 0, err
  403. }
  404. if _, ok := searchMap[article.ArticleId]; !ok {
  405. searchItem := new(models.SearchItem)
  406. searchItem.ArticleId, _ = strconv.Atoi(v.Id)
  407. if len(v.Highlight["BodyText"]) > 0 {
  408. searchItem.Body = v.Highlight["BodyText"]
  409. } else {
  410. bodyRune := []rune(article.BodyText)
  411. bodyRuneLen := len(bodyRune)
  412. if bodyRuneLen > 100 {
  413. bodyRuneLen = 100
  414. }
  415. body := string(bodyRune[:bodyRuneLen])
  416. fmt.Println(body)
  417. searchItem.Body = []string{body}
  418. }
  419. var title string
  420. if len(v.Highlight["Title"]) > 0 {
  421. title = v.Highlight["Title"][0]
  422. } else {
  423. title = article.Title
  424. }
  425. searchItem.Title = title
  426. searchItem.PublishDate = article.PublishDate
  427. result = append(result, searchItem)
  428. searchMap[article.ArticleId] = article.ArticleId
  429. }
  430. }
  431. }
  432. }
  433. total = searchByMatch.Hits.TotalHits.Value
  434. return
  435. }
  436. func GetWeight(length int) []int {
  437. steep := 10
  438. intArr := make([]int, 0)
  439. for i := 1; i <= length; i++ {
  440. if i == 1 {
  441. intArr = append(intArr, 1)
  442. } else {
  443. min := GetArrSum(intArr)
  444. maxVal := utils.GetRandInt(min, min+steep)
  445. intArr = append(intArr, maxVal)
  446. }
  447. }
  448. //数组排序
  449. sort.Slice(intArr, func(i, j int) bool {
  450. return intArr[i] > intArr[j]
  451. })
  452. return intArr
  453. }
  454. func GetArrSum(intArr []int) (sum int) {
  455. for _, val := range intArr {
  456. //累计求和
  457. sum += val
  458. }
  459. return
  460. }