You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

search.go 21 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. package routers
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/setting"
  11. "github.com/olivere/elastic/v7"
  12. )
  13. type SearchRes struct {
  14. Total int64
  15. Result []map[string]interface{}
  16. }
  17. var client *elastic.Client
  18. func InitESClient() {
  19. ESSearchUrl := setting.ESSearchURL
  20. var err error
  21. client, err = elastic.NewClient(elastic.SetSniff(false), elastic.SetURL(ESSearchUrl))
  22. if err != nil {
  23. log.Info("es init error.")
  24. //panic(err)
  25. }
  26. }
  27. func Search(ctx *context.Context) {
  28. keyword := strings.Trim(ctx.Query("q"), " ")
  29. ctx.Data["Keyword"] = keyword
  30. ctx.Data["SortType"] = "newest"
  31. ctx.HTML(200, "explore/search_new")
  32. }
  33. func SearchApi(ctx *context.Context) {
  34. TableName := ctx.Query("TableName")
  35. Key := ctx.Query("Key")
  36. Page := ctx.QueryInt("Page")
  37. PageSize := ctx.QueryInt("PageSize")
  38. OnlyReturnNum := ctx.QueryBool("OnlyReturnNum")
  39. OnlySearchLabel := ctx.QueryBool("OnlySearchLabel")
  40. if Page <= 0 {
  41. Page = 1
  42. }
  43. if PageSize <= 0 || PageSize > 200 {
  44. PageSize = setting.UI.IssuePagingNum
  45. }
  46. if TableName == "repository" {
  47. if OnlySearchLabel {
  48. searchRepoByLabel(ctx, Key, Page, PageSize)
  49. } else {
  50. searchRepo(ctx, "repository-es-index", Key, Page, PageSize, OnlyReturnNum)
  51. }
  52. return
  53. } else if TableName == "issue" {
  54. searchIssue(ctx, "issue-es-index", Key, Page, PageSize, OnlyReturnNum)
  55. return
  56. } else if TableName == "user" {
  57. searchUserOrOrg(ctx, "user-es-index", Key, Page, PageSize, true, OnlyReturnNum)
  58. return
  59. } else if TableName == "org" {
  60. searchUserOrOrg(ctx, "user-es-index", Key, Page, PageSize, false, OnlyReturnNum)
  61. return
  62. } else if TableName == "dataset" {
  63. searchDataSet(ctx, "dataset-es-index", Key, Page, PageSize, OnlyReturnNum)
  64. return
  65. } else if TableName == "pr" {
  66. searchPR(ctx, "issue-es-index", Key, Page, PageSize, OnlyReturnNum)
  67. return
  68. }
  69. }
  70. func searchRepoByLabel(ctx *context.Context, Key string, Page int, PageSize int) {
  71. /*
  72. 项目, ES名称: repository-es-index
  73. 搜索:
  74. name character varying(255) , 项目名称
  75. description text, 项目描述
  76. topics json, 标签
  77. 排序:
  78. updated_unix
  79. num_watches,
  80. num_stars,
  81. num_forks,
  82. */
  83. SortBy := ctx.Query("SortBy")
  84. if SortBy == "" {
  85. SortBy = "updated_unix.keyword"
  86. }
  87. ascending := ctx.QueryBool("Ascending")
  88. log.Info("query searchRepoByLabel start")
  89. if Key != "" {
  90. boolQ := elastic.NewBoolQuery()
  91. topicsQuery := elastic.NewMatchQuery("topics", Key)
  92. boolQ.Should(topicsQuery)
  93. res, err := client.Search("repository-es-index").Query(boolQ).SortBy(elastic.NewScoreSort(), elastic.NewFieldSort(SortBy).Order(ascending)).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("topics")).Do(ctx.Req.Context())
  94. if err == nil {
  95. searchJson, _ := json.Marshal(res)
  96. log.Info("searchJson=" + string(searchJson))
  97. result := makeRepoResult(res, "", false)
  98. ctx.JSON(200, result)
  99. } else {
  100. log.Info("query es error," + err.Error())
  101. ctx.JSON(200, "")
  102. }
  103. }
  104. ctx.JSON(200, "")
  105. }
  106. func searchRepo(ctx *context.Context, TableName string, Key string, Page int, PageSize int, OnlyReturnNum bool) {
  107. /*
  108. 项目, ES名称: repository-es-index
  109. 搜索:
  110. name character varying(255) , 项目名称
  111. description text, 项目描述
  112. topics json, 标签
  113. 排序:
  114. updated_unix
  115. num_watches,
  116. num_stars,
  117. num_forks,
  118. */
  119. SortBy := ctx.Query("SortBy")
  120. if SortBy == "" {
  121. SortBy = "updated_unix.keyword"
  122. }
  123. ascending := ctx.QueryBool("Ascending")
  124. log.Info("query searchRepo start")
  125. if Key != "" {
  126. boolQ := elastic.NewBoolQuery()
  127. nameQuery := elastic.NewMatchQuery("name", Key).Boost(1024).QueryName("f_first")
  128. descriptionQuery := elastic.NewMatchQuery("description", Key).Boost(1.5).QueryName("f_second")
  129. topicsQuery := elastic.NewMatchQuery("topics", Key).Boost(1).QueryName("f_third")
  130. boolQ.Should(nameQuery, descriptionQuery, topicsQuery)
  131. res, err := client.Search(TableName).Query(boolQ).SortBy(elastic.NewScoreSort(), elastic.NewFieldSort(SortBy).Order(ascending)).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("name", "description", "topics")).Do(ctx.Req.Context())
  132. if err == nil {
  133. searchJson, _ := json.Marshal(res)
  134. log.Info("searchJson=" + string(searchJson))
  135. result := makeRepoResult(res, Key, OnlyReturnNum)
  136. ctx.JSON(200, result)
  137. } else {
  138. log.Info("query es error," + err.Error())
  139. ctx.JSON(200, "")
  140. }
  141. } else {
  142. log.Info("query all content.")
  143. //搜索的属性要指定{"timestamp":{"unmapped_type":"date"}}
  144. res, err := client.Search(TableName).SortBy(elastic.NewFieldSort(SortBy).Order(ascending)).From((Page - 1) * PageSize).Size(PageSize).Do(ctx.Req.Context())
  145. if err == nil {
  146. searchJson, _ := json.Marshal(res)
  147. log.Info("searchJson=" + string(searchJson))
  148. result := makeRepoResult(res, "", OnlyReturnNum)
  149. ctx.JSON(200, result)
  150. } else {
  151. log.Info("query es error," + err.Error())
  152. ctx.JSON(200, "")
  153. }
  154. }
  155. }
  156. func makeRepoResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool) *SearchRes {
  157. total := sRes.Hits.TotalHits.Value
  158. result := make([]map[string]interface{}, 0)
  159. if !OnlyReturnNum {
  160. for i, hit := range sRes.Hits.Hits {
  161. log.Info("this is repo query " + fmt.Sprint(i) + " result.")
  162. recordSource := make(map[string]interface{})
  163. source, err := hit.Source.MarshalJSON()
  164. if err == nil {
  165. err = json.Unmarshal(source, &recordSource)
  166. if err == nil {
  167. record := make(map[string]interface{})
  168. record["id"] = hit.Id
  169. record["name"] = getLabelValue("name", recordSource, hit.Highlight)
  170. record["real_name"] = recordSource["name"]
  171. record["owner_name"] = recordSource["owner_name"]
  172. if recordSource["description"] != nil {
  173. desc := getLabelValue("description", recordSource, hit.Highlight)
  174. record["description"] = dealLongText(desc, Key, hit.MatchedQueries)
  175. } else {
  176. record["description"] = ""
  177. }
  178. if Key == "" {
  179. record["hightTopics"] = getLabelValue("topics", recordSource, hit.Highlight)
  180. }
  181. record["num_watches"] = recordSource["num_watches"]
  182. record["num_stars"] = recordSource["num_stars"]
  183. record["num_forks"] = recordSource["num_forks"]
  184. if recordSource["topics"] != nil {
  185. topicsStr := recordSource["topics"].(string)
  186. log.Info("topicsStr=" + topicsStr)
  187. if topicsStr != "null" {
  188. topicsStr = strings.Replace(topicsStr, "\"", "", -1)
  189. topicsStr = topicsStr[1 : len(topicsStr)-1]
  190. log.Info("record[\"topics\"]=" + topicsStr)
  191. topicstmp := strings.Split(topicsStr, ",")
  192. record["topics"] = topicstmp
  193. }
  194. }
  195. if recordSource["avatar"] != nil {
  196. record["avatar"] = setting.AppSubURL + "/repo-avatars/" + recordSource["avatar"].(string)
  197. }
  198. record["updated_unix"] = recordSource["updated_unix"]
  199. record["lang"] = recordSource["lang"]
  200. result = append(result, record)
  201. } else {
  202. log.Info("deal repo source error," + err.Error())
  203. }
  204. } else {
  205. log.Info("deal repo source error," + err.Error())
  206. }
  207. }
  208. }
  209. returnObj := &SearchRes{
  210. Total: total,
  211. Result: result,
  212. }
  213. return returnObj
  214. }
  215. func dealLongText(text string, Key string, MatchedQueries []string) string {
  216. var isNeedToDealText bool
  217. isNeedToDealText = false
  218. if len(MatchedQueries) > 0 && Key != "" {
  219. if MatchedQueries[0] == "f_second" || MatchedQueries[0] == "f_third" {
  220. isNeedToDealText = true
  221. }
  222. }
  223. stringlen := len(text)
  224. if isNeedToDealText && stringlen > 200 {
  225. index := strings.Index(text, Key)
  226. if index > 0 {
  227. start := index - 50
  228. if start < 0 {
  229. start = 0
  230. }
  231. end := index + 150
  232. if end >= stringlen {
  233. end = stringlen
  234. }
  235. return text[start:end]
  236. } else {
  237. return text[0:200]
  238. }
  239. } else {
  240. if stringlen > 200 {
  241. return text[0:200]
  242. } else {
  243. return text
  244. }
  245. }
  246. }
  247. func searchUserOrOrg(ctx *context.Context, TableName string, Key string, Page int, PageSize int, IsQueryUser bool, OnlyReturnNum bool) {
  248. /*
  249. 用户或者组织 ES名称: user-es-index
  250. 搜索:
  251. name , 名称
  252. full_name 全名
  253. description 描述或者简介
  254. 排序:
  255. created_unix
  256. 名称字母序
  257. */
  258. SortBy := ctx.Query("SortBy")
  259. if SortBy == "" {
  260. SortBy = "created_unix.keyword"
  261. }
  262. ascending := ctx.QueryBool("Ascending")
  263. boolQ := elastic.NewBoolQuery()
  264. typeValue := 1
  265. if IsQueryUser {
  266. typeValue = 0
  267. }
  268. UserOrOrgQuery := elastic.NewTermQuery("type", typeValue)
  269. if Key != "" {
  270. boolKeyQ := elastic.NewBoolQuery()
  271. log.Info("issue Key=" + Key)
  272. nameQuery := elastic.NewMatchQuery("name", Key).Boost(2).QueryName("f_first")
  273. full_nameQuery := elastic.NewMatchQuery("full_name", Key).Boost(1.5).QueryName("f_second")
  274. descriptionQuery := elastic.NewMatchQuery("description", Key).Boost(1).QueryName("f_third")
  275. boolKeyQ.Should(nameQuery, full_nameQuery, descriptionQuery)
  276. boolQ.Must(UserOrOrgQuery, boolKeyQ)
  277. } else {
  278. boolQ.Must(UserOrOrgQuery)
  279. }
  280. res, err := client.Search(TableName).Query(boolQ).Sort(SortBy, ascending).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("name", "full_name", "description")).Do(ctx.Req.Context())
  281. if err == nil {
  282. searchJson, _ := json.Marshal(res)
  283. log.Info("searchJson=" + string(searchJson))
  284. result := makeUserOrOrgResult(res, Key, ctx, OnlyReturnNum)
  285. ctx.JSON(200, result)
  286. } else {
  287. log.Info("query es error," + err.Error())
  288. ctx.JSON(200, "")
  289. }
  290. }
  291. func getLabelValue(key string, recordSource map[string]interface{}, searchHighliht elastic.SearchHitHighlight) string {
  292. if value, ok := searchHighliht[key]; !ok {
  293. if recordSource[key] != nil {
  294. return recordSource[key].(string)
  295. } else {
  296. return ""
  297. }
  298. } else {
  299. return value[0]
  300. }
  301. }
  302. func makeUserOrOrgResult(sRes *elastic.SearchResult, Key string, ctx *context.Context, OnlyReturnNum bool) *SearchRes {
  303. total := sRes.Hits.TotalHits.Value
  304. result := make([]map[string]interface{}, 0)
  305. if !OnlyReturnNum {
  306. for i, hit := range sRes.Hits.Hits {
  307. log.Info("this is user query " + fmt.Sprint(i) + " result.")
  308. recordSource := make(map[string]interface{})
  309. source, err := hit.Source.MarshalJSON()
  310. if err == nil {
  311. err = json.Unmarshal(source, &recordSource)
  312. if err == nil {
  313. record := make(map[string]interface{})
  314. record["id"] = hit.Id
  315. record["name"] = getLabelValue("name", recordSource, hit.Highlight)
  316. record["real_name"] = recordSource["name"]
  317. record["full_name"] = getLabelValue("full_name", recordSource, hit.Highlight)
  318. if recordSource["description"] != nil {
  319. desc := getLabelValue("description", recordSource, hit.Highlight)
  320. record["description"] = dealLongText(desc, Key, hit.MatchedQueries)
  321. } else {
  322. record["description"] = ""
  323. }
  324. if ctx.User != nil {
  325. record["email"] = recordSource["email"]
  326. } else {
  327. record["email"] = ""
  328. }
  329. record["location"] = recordSource["location"]
  330. record["website"] = recordSource["website"]
  331. record["num_repos"] = recordSource["num_repos"]
  332. record["num_teams"] = recordSource["num_teams"]
  333. record["num_members"] = recordSource["num_members"]
  334. record["avatar"] = strings.TrimRight(setting.AppSubURL, "/") + "/user/avatar/" + recordSource["name"].(string) + "/" + strconv.Itoa(-1)
  335. record["updated_unix"] = recordSource["updated_unix"]
  336. record["created_unix"] = recordSource["created_unix"]
  337. result = append(result, record)
  338. } else {
  339. log.Info("deal user source error," + err.Error())
  340. }
  341. } else {
  342. log.Info("deal user source error," + err.Error())
  343. }
  344. }
  345. }
  346. returnObj := &SearchRes{
  347. Total: total,
  348. Result: result,
  349. }
  350. return returnObj
  351. }
  352. func searchDataSet(ctx *context.Context, TableName string, Key string, Page int, PageSize int, OnlyReturnNum bool) {
  353. /*
  354. 数据集,ES名称:dataset-es-index
  355. 搜索:
  356. title , 名称
  357. description 描述
  358. category 标签
  359. file_name 数据集文件名称
  360. 排序:
  361. download_times
  362. */
  363. SortBy := ctx.Query("SortBy")
  364. if SortBy == "" {
  365. SortBy = "download_times.keyword"
  366. }
  367. ascending := ctx.QueryBool("Ascending")
  368. log.Info("query searchRepo start")
  369. boolQ := elastic.NewBoolQuery()
  370. if Key != "" {
  371. nameQuery := elastic.NewMatchQuery("title", Key).Boost(2).QueryName("f_first")
  372. descQuery := elastic.NewMatchQuery("description", Key).Boost(1.5).QueryName("f_second")
  373. fileNameQuery := elastic.NewMatchQuery("file_name", Key).Boost(1).QueryName("f_third")
  374. categoryQuery := elastic.NewMatchQuery("category", Key).Boost(1).QueryName("f_fourth")
  375. boolQ.Should(nameQuery, descQuery, categoryQuery, fileNameQuery)
  376. res, err := client.Search(TableName).Query(boolQ).Sort(SortBy, ascending).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("title", "description", "file_name", "category")).Do(ctx.Req.Context())
  377. if err == nil {
  378. searchJson, _ := json.Marshal(res)
  379. log.Info("searchJson=" + string(searchJson))
  380. result := makeDatasetResult(res, Key, OnlyReturnNum)
  381. ctx.JSON(200, result)
  382. } else {
  383. log.Info("query es error," + err.Error())
  384. }
  385. } else {
  386. log.Info("query all content.")
  387. //搜索的属性要指定{"timestamp":{"unmapped_type":"date"}}
  388. res, err := client.Search(TableName).Sort(SortBy, ascending).From((Page - 1) * PageSize).Size(PageSize).Do(ctx.Req.Context())
  389. if err == nil {
  390. searchJson, _ := json.Marshal(res)
  391. log.Info("searchJson=" + string(searchJson))
  392. result := makeDatasetResult(res, "", OnlyReturnNum)
  393. ctx.JSON(200, result)
  394. } else {
  395. log.Info("query es error," + err.Error())
  396. ctx.JSON(200, "")
  397. }
  398. }
  399. }
  400. func makeDatasetResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool) *SearchRes {
  401. total := sRes.Hits.TotalHits.Value
  402. result := make([]map[string]interface{}, 0)
  403. if !OnlyReturnNum {
  404. for i, hit := range sRes.Hits.Hits {
  405. log.Info("this is dataset query " + fmt.Sprint(i) + " result.")
  406. recordSource := make(map[string]interface{})
  407. source, err := hit.Source.MarshalJSON()
  408. if err == nil {
  409. err = json.Unmarshal(source, &recordSource)
  410. if err == nil {
  411. record := make(map[string]interface{})
  412. record["id"] = hit.Id
  413. userIdStr := recordSource["user_id"].(string)
  414. userId, cerr := strconv.ParseInt(userIdStr, 10, 64)
  415. if cerr == nil {
  416. user, errUser := models.GetUserByID(userId)
  417. if errUser == nil {
  418. record["owerName"] = user.GetDisplayName()
  419. record["avatar"] = user.RelAvatarLink()
  420. }
  421. }
  422. setRepoInfo(recordSource, record)
  423. record["title"] = getLabelValue("title", recordSource, hit.Highlight)
  424. record["category"] = getLabelValue("category", recordSource, hit.Highlight)
  425. if recordSource["description"] != nil {
  426. desc := getLabelValue("description", recordSource, hit.Highlight)
  427. record["description"] = dealLongText(desc, Key, hit.MatchedQueries)
  428. } else {
  429. record["description"] = ""
  430. }
  431. record["file_name"] = recordSource["file_name"]
  432. record["task"] = recordSource["task"]
  433. record["download_times"] = recordSource["download_times"]
  434. record["created_unix"] = recordSource["created_unix"]
  435. result = append(result, record)
  436. } else {
  437. log.Info("deal dataset source error," + err.Error())
  438. }
  439. } else {
  440. log.Info("deal dataset source error," + err.Error())
  441. }
  442. }
  443. }
  444. returnObj := &SearchRes{
  445. Total: total,
  446. Result: result,
  447. }
  448. return returnObj
  449. }
  450. func searchIssue(ctx *context.Context, TableName string, Key string, Page int, PageSize int, OnlyReturnNum bool) {
  451. /*
  452. 任务,合并请求 ES名称:issue-es-index
  453. 搜索:
  454. name character varying(255) , 标题
  455. content text, 内容
  456. comment text, 评论
  457. 排序:
  458. updated_unix
  459. */
  460. SortBy := ctx.Query("SortBy")
  461. if SortBy == "" {
  462. SortBy = "updated_unix.keyword"
  463. }
  464. ascending := ctx.QueryBool("Ascending")
  465. boolQ := elastic.NewBoolQuery()
  466. isIssueQuery := elastic.NewTermQuery("is_pull", "f")
  467. if Key != "" {
  468. boolKeyQ := elastic.NewBoolQuery()
  469. log.Info("issue Key=" + Key)
  470. nameQuery := elastic.NewMatchQuery("name", Key).Boost(2).QueryName("f_first")
  471. contentQuery := elastic.NewMatchQuery("content", Key).Boost(1.5).QueryName("f_second")
  472. commentQuery := elastic.NewMatchQuery("comment", Key).Boost(1).QueryName("f_third")
  473. boolKeyQ.Should(nameQuery, contentQuery, commentQuery)
  474. boolQ.Must(isIssueQuery, boolKeyQ)
  475. } else {
  476. boolQ.Must(isIssueQuery)
  477. }
  478. res, err := client.Search(TableName).Query(boolQ).Sort(SortBy, ascending).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("name", "content", "comment")).Do(ctx.Req.Context())
  479. if err == nil {
  480. searchJson, _ := json.Marshal(res)
  481. log.Info("searchJson=" + string(searchJson))
  482. result := makeIssueResult(res, Key, OnlyReturnNum)
  483. ctx.JSON(200, result)
  484. } else {
  485. log.Info("query es error," + err.Error())
  486. }
  487. }
  488. func queryHighlight(names ...string) *elastic.Highlight {
  489. re := elastic.NewHighlight()
  490. for i := 0; i < len(names); i++ {
  491. field := &elastic.HighlighterField{
  492. Name: names[i],
  493. }
  494. re.Fields(field)
  495. }
  496. re.PreTags("<font color='red'>")
  497. re.PostTags("</font>")
  498. return re
  499. }
  500. func setRepoInfo(recordSource map[string]interface{}, record map[string]interface{}) {
  501. repoIdstr := recordSource["repo_id"].(string)
  502. repoId, cerr := strconv.ParseInt(repoIdstr, 10, 64)
  503. if cerr == nil {
  504. repo, errRepo := models.GetRepositoryByID(repoId)
  505. if errRepo == nil {
  506. log.Info("repo_url=" + repo.FullName())
  507. record["repoUrl"] = repo.FullName()
  508. record["avatar"] = repo.RelAvatarLink()
  509. } else {
  510. log.Info("repo err=" + errRepo.Error())
  511. }
  512. } else {
  513. log.Info("parse int err=" + cerr.Error())
  514. }
  515. }
  516. func makeIssueResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool) *SearchRes {
  517. total := sRes.Hits.TotalHits.Value
  518. result := make([]map[string]interface{}, 0)
  519. if !OnlyReturnNum {
  520. for i, hit := range sRes.Hits.Hits {
  521. log.Info("this is issue query " + fmt.Sprint(i) + " result.")
  522. recordSource := make(map[string]interface{})
  523. source, err := hit.Source.MarshalJSON()
  524. if err == nil {
  525. err = json.Unmarshal(source, &recordSource)
  526. if err == nil {
  527. record := make(map[string]interface{})
  528. record["id"] = hit.Id
  529. record["repo_id"] = recordSource["repo_id"]
  530. log.Info("recordSource[\"repo_id\"]=" + fmt.Sprint(recordSource["repo_id"]))
  531. setRepoInfo(recordSource, record)
  532. record["name"] = getLabelValue("name", recordSource, hit.Highlight)
  533. if recordSource["content"] != nil {
  534. desc := getLabelValue("content", recordSource, hit.Highlight)
  535. record["content"] = dealLongText(desc, Key, hit.MatchedQueries)
  536. if _, ok := hit.Highlight["content"]; !ok {
  537. if _, ok_comment := hit.Highlight["comment"]; ok_comment {
  538. desc := getLabelValue("comment", recordSource, hit.Highlight)
  539. record["content"] = dealLongText(desc, Key, hit.MatchedQueries)
  540. }
  541. }
  542. } else {
  543. if recordSource["comment"] != nil {
  544. desc := getLabelValue("comment", recordSource, hit.Highlight)
  545. record["content"] = dealLongText(desc, Key, hit.MatchedQueries)
  546. }
  547. }
  548. if recordSource["pr_id"] != nil {
  549. record["pr_id"] = recordSource["pr_id"]
  550. }
  551. record["num_comments"] = recordSource["num_comments"]
  552. record["is_closed"] = recordSource["is_closed"]
  553. record["updated_unix"] = recordSource["updated_unix"]
  554. result = append(result, record)
  555. } else {
  556. log.Info("deal issue source error," + err.Error())
  557. }
  558. } else {
  559. log.Info("deal issue source error," + err.Error())
  560. }
  561. }
  562. }
  563. returnObj := &SearchRes{
  564. Total: total,
  565. Result: result,
  566. }
  567. return returnObj
  568. }
  569. func searchPR(ctx *context.Context, TableName string, Key string, Page int, PageSize int, OnlyReturnNum bool) {
  570. /*
  571. 任务,合并请求 ES名称:issue-es-index
  572. 搜索:
  573. name character varying(255) , 标题
  574. content text, 内容
  575. comment text, 评论
  576. 排序:
  577. updated_unix
  578. */
  579. SortBy := ctx.Query("SortBy")
  580. if SortBy == "" {
  581. SortBy = "updated_unix.keyword"
  582. }
  583. ascending := ctx.QueryBool("Ascending")
  584. boolQ := elastic.NewBoolQuery()
  585. isPRQuery := elastic.NewTermQuery("is_pull", "t")
  586. if Key != "" {
  587. boolKeyQ := elastic.NewBoolQuery()
  588. log.Info("issue Key=" + Key)
  589. nameQuery := elastic.NewMatchQuery("name", Key).Boost(2).QueryName("f_first")
  590. contentQuery := elastic.NewMatchQuery("content", Key).Boost(1.5).QueryName("f_second")
  591. commentQuery := elastic.NewMatchQuery("comment", Key).Boost(1).QueryName("f_third")
  592. boolKeyQ.Should(nameQuery, contentQuery, commentQuery)
  593. boolQ.Must(isPRQuery, boolKeyQ)
  594. } else {
  595. boolQ.Must(isPRQuery)
  596. }
  597. res, err := client.Search(TableName).Query(boolQ).Sort(SortBy, ascending).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("name", "content", "comment")).Do(ctx.Req.Context())
  598. if err == nil {
  599. result := makeIssueResult(res, Key, OnlyReturnNum)
  600. ctx.JSON(200, result)
  601. } else {
  602. log.Info("query es error," + err.Error())
  603. }
  604. }