main.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "strings"
  7. "time"
  8. e "github.com/dabory/abango-rest/etc"
  9. "github.com/elastic/go-elasticsearch/v7"
  10. "github.com/elastic/go-elasticsearch/v7/esutil"
  11. )
  12. var ( //Prefix
  13. ES_CLIENT *elasticsearch.Client // 기본 Elastic Client
  14. )
  15. type UrlBdPageRet struct {
  16. Page []SchUrlBd
  17. }
  18. type ScrUrlBdPage struct {
  19. Hits struct {
  20. Hits []ScrUrlBdRow `json:"hits"`
  21. MaxScore float64 `json:"max_score"`
  22. Total struct {
  23. Relation string `json:"relation"`
  24. Value int `json:"value"`
  25. } `json:"total"`
  26. } `json:"hits"`
  27. }
  28. type ScrUrlBdRow struct {
  29. ID string `json:"_id"`
  30. Index string `json:"_index"`
  31. Score float64 `json:"_score"`
  32. Source SchUrlBd `json:"_source"`
  33. Type string `json:"_type"`
  34. }
  35. type SchUrlBd struct {
  36. Id string //PdplinkHash
  37. CreatedAt time.Time `xorm:"not null DATETIME"`
  38. UpdatedAt time.Time `xorm:"not null DATETIME"`
  39. HostName string //DomainHash
  40. TargetPath string
  41. PdpHtmlHash string
  42. }
  43. type SimpleFilters struct {
  44. SimpleFilters []SimpleFilter
  45. }
  46. type SimpleFilter struct {
  47. Condition string
  48. Name string
  49. Value string
  50. }
  51. func (t *UrlBdPageRet) PageName() string {
  52. return e.PageName(t.Page)
  53. }
  54. func (t *UrlBdPageRet) RecordName() string { //필수
  55. return "Id of " + e.NumToStr(t.PageName) + " in " + e.PageName(*t) + " "
  56. }
  57. func init() {
  58. var err error
  59. ES_CLIENT, _ = elasticsearch.NewClient(elasticsearch.Config{
  60. Addresses: []string{
  61. "http://kibana-seoul-c.daboryhost.com:9200",
  62. },
  63. Username: "elastic",
  64. Password: "elasticpassword",
  65. })
  66. if err != nil {
  67. e.LogErr("daslkjlasjfd", "Elastic NewClient", err)
  68. return
  69. }
  70. }
  71. func main() {
  72. var t UrlBdPageRet
  73. // queryStr := "HostName like '*seoulknit.com*'"
  74. queryStr := " Id like '*259beeae13757f9d411dded768342505*' AND HostName like '*seoulknit.com*' "
  75. // queryStr := "Id='259beeae13757f9d411dded768342505' AND HostName='seoulknit.com' AND TargetPath='/shop/warp-cardigan/'"
  76. // queryStr := ""
  77. // queryStr := "HostName='seoulknit.com'"
  78. // queryStr = "HostName='seoulknit.com' AND TargetPath='/shop/standard-knit-pants_blacklight-gray/'"
  79. // queryStr = "TargetPath='/shop/warp-cardigan/'"
  80. ascStr := "Id"
  81. descStr := "TargetPath, PdpHtmlHash"
  82. // ascStr := ""
  83. // descStr := ""
  84. queryClauses := ElaQueryComposer(queryStr)
  85. sortClauses := ElaSortComposer(ascStr + "|" + descStr)
  86. ret, _ := json.Marshal(sortClauses)
  87. // fmt.Println("ret", string(ret))
  88. // queryClauses := map[string]interface{}{
  89. // "bool": map[string]interface{}{
  90. // "must": []interface{}{
  91. // map[string]interface{}{
  92. // "wildcard": map[string]interface{}{
  93. // "Id": "*259beeae13757f9d411dded768342505*",
  94. // },
  95. // },
  96. // map[string]interface{}{
  97. // "wildcard": map[string]interface{}{
  98. // "HostName": "*seoulknit.com*",
  99. // },
  100. // },
  101. // },
  102. // },
  103. // }
  104. fmt.Println("queryClauses", queryClauses)
  105. // Create a bool query with two must clauses
  106. query := map[string]interface{}{
  107. "query": queryClauses,
  108. "sort": sortClauses,
  109. "size": 10,
  110. "from": 0,
  111. }
  112. res, err := ES_CLIENT.Search(
  113. ES_CLIENT.Search.WithContext(context.Background()),
  114. ES_CLIENT.Search.WithIndex(t.PageName()),
  115. ES_CLIENT.Search.WithBody(esutil.NewJSONReader(query)),
  116. )
  117. defer res.Body.Close()
  118. if err != nil {
  119. fmt.Println("qrlhbdf", "Search Error in index: ", err)
  120. } else {
  121. if res.IsError() {
  122. fmt.Println("qrlhbdf", "Search Error in index: ", res)
  123. }
  124. }
  125. var resJs ScrUrlBdPage
  126. if err := json.NewDecoder(res.Body).Decode(&resJs); err != nil {
  127. fmt.Println("qrlhbdf", "Error decoding ")
  128. }
  129. for _, row := range resJs.Hits.Hits {
  130. t.Page = append(t.Page, row.Source)
  131. }
  132. // ret, _ = json.Marshal(t)
  133. ret, _ = json.MarshalIndent(t, "", "\t")
  134. fmt.Println("result: ", string(ret))
  135. return
  136. }
  137. func ElaQueryComposer(qry string) map[string]interface{} {
  138. // queryStr := "id='kkk' AND ( solution_code = 'WooCommerce' OR host_name = 'andadd.kr' )"
  139. qryTmp := strings.Replace(strings.Replace(qry, " and ", " AND ", -1), " or ", " OR ", -1)
  140. qryTmp = strings.Replace(qry, " like ", " LIKE ", -1)
  141. dbqry1 := strings.Split(qryTmp, " AND ")
  142. var t SimpleFilters
  143. if qry == "" {
  144. fieldsAndValues := t.SimpleFilters
  145. var matchClauses []map[string]interface{}
  146. for _, fieldAndValue := range fieldsAndValues {
  147. matchClauses = append(matchClauses, map[string]interface{}{
  148. "match": map[string]interface{}{
  149. fieldAndValue.Name: fieldAndValue.Value,
  150. },
  151. })
  152. }
  153. return map[string]interface{}{
  154. "bool": map[string]interface{}{
  155. "must": matchClauses,
  156. },
  157. }
  158. }
  159. for i := 0; i < (len(dbqry1)); i++ {
  160. clause := dbqry1[i]
  161. clauses := []string{}
  162. dbqry2 := strings.Split(strings.Trim(strings.Trim(clause, "("), ")"), " OR ")
  163. if len(dbqry2) > 1 {
  164. clauses = append(clauses, dbqry2...)
  165. } else {
  166. clauses = append(clauses, clause)
  167. }
  168. for k := 0; k < len(clauses); k++ {
  169. var v SimpleFilter
  170. c := clauses[k]
  171. if strings.Contains(c, "=") {
  172. keyValue := strings.Split(c, "=")
  173. v.Condition = "match"
  174. v.Name = strings.Replace(keyValue[0], " ", "", -1)
  175. v.Value = strings.Replace(strings.Replace(keyValue[1], "'", "", -1), " ", "", -1)
  176. t.SimpleFilters = append(t.SimpleFilters, v)
  177. } else if strings.Contains(c, " LIKE ") {
  178. keyValue := strings.Split(c, " LIKE ")
  179. v.Condition = "wildcard"
  180. v.Name = strings.Replace(keyValue[0], " ", "", -1)
  181. v.Value = strings.Replace(strings.Replace(keyValue[1], "'", "", -1), " ", "", -1)
  182. t.SimpleFilters = append(t.SimpleFilters, v)
  183. }
  184. }
  185. }
  186. fieldsAndValues := t.SimpleFilters
  187. var matchClauses []map[string]interface{}
  188. for _, fieldAndValue := range fieldsAndValues {
  189. matchClauses = append(matchClauses, map[string]interface{}{
  190. fieldAndValue.Condition: map[string]interface{}{
  191. // "match": map[string]interface{}{
  192. fieldAndValue.Name: fieldAndValue.Value,
  193. },
  194. })
  195. }
  196. // fmt.Println(matchClauses)
  197. return map[string]interface{}{
  198. "bool": map[string]interface{}{
  199. "must": matchClauses,
  200. },
  201. }
  202. }
  203. func ElaSortComposer(sort string) (sortClauses []map[string]interface{}) {
  204. // fmt.Println(sort)
  205. // Task 2
  206. // You need to run in kibana to make the filed as sort acceptable
  207. // PUT my-index-000001/_mapping
  208. // {
  209. // "properties": {
  210. // "my_field": {
  211. // "type": "text",
  212. // "fielddata": true
  213. // }
  214. // }
  215. // }
  216. // var sortClauses []map[string]interface{}
  217. // fmt.Println("sort", strings.ReplaceAll(sort, " ", ""))
  218. sortHandle := strings.Split(strings.ReplaceAll(sort, " ", ""), "|")
  219. // asc
  220. asc := string(sortHandle[0])
  221. fieldsAcs := strings.Split(asc, ",")
  222. fmt.Println(fieldsAcs)
  223. if sortHandle[0] != "" {
  224. for i := 0; i < len(fieldsAcs); i++ {
  225. sortOne := map[string]interface{}{
  226. fmt.Sprintf("%v.keyword", fieldsAcs[i]): map[string]interface{}{
  227. "order": "asc",
  228. },
  229. }
  230. sortClauses = append(sortClauses, sortOne)
  231. }
  232. } else {
  233. sortOne := map[string]interface{}{}
  234. sortClauses = append(sortClauses, sortOne)
  235. }
  236. // desc
  237. if sortHandle[1] != "" {
  238. desc := string(sortHandle[1])
  239. fieldsDecs := strings.Split(desc, ",")
  240. for i := 0; i < len(fieldsDecs); i++ {
  241. sortOne := map[string]interface{}{
  242. fmt.Sprintf("%v.keyword", fieldsDecs[i]): map[string]interface{}{
  243. "order": "desc",
  244. },
  245. }
  246. sortClauses = append(sortClauses, sortOne)
  247. }
  248. } else {
  249. sortOne := map[string]interface{}{}
  250. sortClauses = append(sortClauses, sortOne)
  251. }
  252. return sortClauses
  253. }