|
@@ -1,15 +1,5 @@
|
|
|
package es
|
|
|
|
|
|
-import (
|
|
|
- MC "app.yhyue.com/moapp/jybase/common"
|
|
|
- elastic "app.yhyue.com/moapp/jybase/esv1"
|
|
|
- "fmt"
|
|
|
- "jyBXCore/rpc/entity"
|
|
|
- "strconv"
|
|
|
- "strings"
|
|
|
- "time"
|
|
|
-)
|
|
|
-
|
|
|
const (
|
|
|
queryByIds = `{"query":{"bool":{"must":[{"terms":{"_id":[%s]}}]}}}`
|
|
|
multiMatch = `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
|
|
@@ -23,9 +13,17 @@ const (
|
|
|
gte = `"gte": %s`
|
|
|
lte = `"lte": %s`
|
|
|
queryPublishTime = `{"range":{"publishtime":{%s}}}`
|
|
|
+
|
|
|
+ query_bool_should = `{"bool":{"should":[%s],"minimum_should_match": 1}}`
|
|
|
+ bidSearch_sort = `{"dataweight":-1,"publishtime":-1}`
|
|
|
+ bidSearch_field_1 = `"_id","title","publishtime","dataweight","toptype","subtype","type","area","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"` //,"filetext"
|
|
|
+ bidSearch_field = bidSearch_field_1 + `,"bidopentime","winner","buyer","projectname","projectcode","projectinfo"`
|
|
|
+
|
|
|
+ DefaultFields = `"title"` //最新招标信息
|
|
|
)
|
|
|
|
|
|
-var topType = map[string]string{
|
|
|
+//
|
|
|
+var topTypeMap = map[string]string{
|
|
|
"招标预告": "预告",
|
|
|
"招标公告": "招标",
|
|
|
"招标结果": "结果",
|
|
@@ -33,268 +31,3 @@ var topType = map[string]string{
|
|
|
"拟建项目": "拟建",
|
|
|
"采购意向": "采购意向",
|
|
|
}
|
|
|
-
|
|
|
-type SearchQuery struct{}
|
|
|
-
|
|
|
-func (s *SearchQuery) BiddingSearchQuery(bsp *entity.BiddingSearchParams) (qstr string) {
|
|
|
- if len(bsp.SelectIds) > 0 {
|
|
|
- return fmt.Sprintf(queryByIds, `"`+strings.Join(bsp.SelectIds, `","`)+`"`)
|
|
|
- }
|
|
|
-
|
|
|
- var bools []string
|
|
|
- var musts = []string{fmt.Sprintf(`{"range":{"comeintime":{"lt":%d}}}`, bsp.ComeInTime)}
|
|
|
- var mustNot []string
|
|
|
- //地区
|
|
|
- var area []string
|
|
|
- //省份
|
|
|
- if len(bsp.Province) > 0 {
|
|
|
- areaquery := `{"terms":{"area":[`
|
|
|
- for k, v := range bsp.Province {
|
|
|
- if k > 0 {
|
|
|
- areaquery += `,`
|
|
|
- }
|
|
|
- areaquery += `"` + v + `"`
|
|
|
- }
|
|
|
- areaquery += `]}}`
|
|
|
- area = append(area, areaquery)
|
|
|
- }
|
|
|
- //城市
|
|
|
- if len(bsp.City) > 0 {
|
|
|
- areaquery := `{"terms":{"city":[`
|
|
|
- for k, v := range bsp.City {
|
|
|
- if k > 0 {
|
|
|
- areaquery += `,`
|
|
|
- }
|
|
|
- areaquery += `"` + v + `"`
|
|
|
- }
|
|
|
- areaquery += `]}}`
|
|
|
- area = append(area, areaquery)
|
|
|
- }
|
|
|
- if len(area) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolShould, strings.Join(area, ",")))
|
|
|
- }
|
|
|
- //检索日期
|
|
|
- //发布时间
|
|
|
- startTime := ""
|
|
|
- now := time.Unix(bsp.ComeInTime, 0)
|
|
|
- endTime := fmt.Sprintf("%d", now.Unix())
|
|
|
- if strings.Contains(bsp.PublishTime, "_") { //设置检索日期
|
|
|
- timeQuery := ``
|
|
|
- startTime = strings.Split(bsp.PublishTime, "_")[0]
|
|
|
- endTimeTmp := now
|
|
|
- if etime := strings.Split(bsp.PublishTime, "_")[1]; etime != "" {
|
|
|
- etTime := time.Unix(MC.Int64All(etime), 0)
|
|
|
- endTimeTmp = time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local)
|
|
|
- }
|
|
|
- //结束时间必须小于筛选时间
|
|
|
- if endTimeTmp.After(now) {
|
|
|
- endTimeTmp = now
|
|
|
- }
|
|
|
- endTime = fmt.Sprintf("%d", endTimeTmp.Unix())
|
|
|
- if startTime != "" {
|
|
|
- timeQuery += fmt.Sprintf(gte, startTime)
|
|
|
- }
|
|
|
- if startTime != "" && endTime != "" {
|
|
|
- timeQuery += `,`
|
|
|
- }
|
|
|
- if endTime != "" {
|
|
|
- timeQuery += fmt.Sprintf(lte, endTime)
|
|
|
- }
|
|
|
- musts = append(musts, fmt.Sprintf(queryPublishTime, timeQuery))
|
|
|
- }
|
|
|
- //信息类型 toptype 一级;subtype 二级;
|
|
|
- if bsp.Subtype != "" || bsp.Toptype != "" {
|
|
|
- var subQuery string
|
|
|
- var topTypes = strings.Split(bsp.Toptype, ",")
|
|
|
- var subTypes = strings.Split(bsp.Subtype, ",")
|
|
|
- for _, v := range strings.Split(bsp.Subtype, ",") {
|
|
|
- if v1, ok := topType[v]; ok {
|
|
|
- topTypes = append(topTypes, fmt.Sprintf(`"%s"`, v1))
|
|
|
- } else {
|
|
|
- subTypes = append(subTypes, fmt.Sprintf(`"%s"`, v))
|
|
|
- }
|
|
|
- }
|
|
|
- if len(subTypes) > 0 && len(topTypes) > 0 {
|
|
|
- subQuery = fmt.Sprintf(`{"bool": {"should": [{"terms": {"subtype": [%s]}},{"terms": {"toptype": [%s]}}]}}`, strings.Join(subTypes, ","), strings.Join(topTypes, ","))
|
|
|
- } else if len(subTypes) > 0 {
|
|
|
- subQuery = fmt.Sprintf(`{"terms":{"subtype":[%s]}}`, strings.Join(subTypes, ","))
|
|
|
- } else if len(topTypes) > 0 {
|
|
|
- subQuery = fmt.Sprintf(`{"terms":{"toptype":[%s]}}`, strings.Join(topTypes, ","))
|
|
|
- }
|
|
|
- musts = append(musts, subQuery)
|
|
|
- }
|
|
|
- //行业
|
|
|
- if len(bsp.Industry) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolMust, "s_subscopeclass", `"`+strings.Join(bsp.Industry, `","`)+`"`))
|
|
|
- }
|
|
|
- //采购单位
|
|
|
- if len(bsp.Buyer) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolMust, "buyer", `"`+strings.Join(bsp.Buyer, `","`)+`"`))
|
|
|
- }
|
|
|
- //采购单位类型
|
|
|
- if len(bsp.BuyerClass) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolMust, "buyerclass", `"`+strings.Join(bsp.BuyerClass, `","`)+`"`))
|
|
|
- }
|
|
|
- //中标单位
|
|
|
- if len(bsp.Winner) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolMust, "s_winner", `"`+strings.Join(bsp.Winner, `","`)+`"`))
|
|
|
- }
|
|
|
- //价格区间
|
|
|
- if bsp.MinPrice != "" || bsp.MaxPrice != "" {
|
|
|
- _minPrice := ""
|
|
|
- _maxPrice := ""
|
|
|
- sq := ``
|
|
|
- if bsp.MinPrice != "" {
|
|
|
- min, _ := strconv.ParseFloat(bsp.MinPrice, 64)
|
|
|
- _minPrice = fmt.Sprintf("%.0f", min*10000)
|
|
|
- if _minPrice == "0" {
|
|
|
- _minPrice = ""
|
|
|
- }
|
|
|
- }
|
|
|
- if bsp.MaxPrice != "" {
|
|
|
- max, _ := strconv.ParseFloat(bsp.MaxPrice, 64)
|
|
|
- _maxPrice = fmt.Sprintf("%.0f", max*10000)
|
|
|
- if _maxPrice == "0" {
|
|
|
- _maxPrice = ""
|
|
|
- }
|
|
|
- }
|
|
|
- if _minPrice != "" {
|
|
|
- sq += fmt.Sprintf(gte, _minPrice)
|
|
|
- }
|
|
|
- if _minPrice != "" && _maxPrice != "" {
|
|
|
- sq += `,`
|
|
|
- }
|
|
|
- if _maxPrice != "" {
|
|
|
- sq += fmt.Sprintf(lte, _maxPrice)
|
|
|
- }
|
|
|
- if _minPrice != "" || _maxPrice != "" {
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(queryPrice, sq, sq)))
|
|
|
- }
|
|
|
- }
|
|
|
- boolsNum := 0
|
|
|
- selectType := bsp.SelectType
|
|
|
- //关键词
|
|
|
- if len(bsp.Keyword) > 0 {
|
|
|
- boolsNum = 1
|
|
|
- queryItem := ""
|
|
|
- if selectType == "" {
|
|
|
- queryItem = "title"
|
|
|
- } else if selectType == "all" {
|
|
|
- queryItem = "detail\", \"title"
|
|
|
- } else {
|
|
|
- //搜索开关打开 包含标题和正文 只匹配正文
|
|
|
- if bsp.SearchTypeSwitch && s.DetailANDTitle(selectType) {
|
|
|
- if strings.Contains(selectType, "title,") {
|
|
|
- selectType = strings.Replace(selectType, "title,", "", -1)
|
|
|
- } else if strings.Contains(selectType, ",title") {
|
|
|
- selectType = strings.Replace(selectType, ",title", "", -1)
|
|
|
- }
|
|
|
- }
|
|
|
- queryItem = strings.ReplaceAll(selectType, ",", "\",\"")
|
|
|
- }
|
|
|
- multiMatchNew := fmt.Sprintf(multiMatch, "%s", "\""+queryItem+"\"")
|
|
|
- for _, v := range bsp.Keyword {
|
|
|
- var should []string
|
|
|
- var mustNot []string
|
|
|
- if v.Keyword != "" {
|
|
|
- if strings.Contains(v.Keyword, "+") {
|
|
|
- for _, vk := range strings.Split(v.Keyword, "+") {
|
|
|
- //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
|
|
|
- if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vk))) == 1 {
|
|
|
- queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
- shouldKeys := fmt.Sprintf(multiMatch, "\""+vk+"\"", "\""+queryItem+"\"")
|
|
|
- should = append(should, shouldKeys)
|
|
|
- } else {
|
|
|
- should = append(should, fmt.Sprintf(multiMatchNew, "\""+vk+"\""))
|
|
|
- }
|
|
|
- }
|
|
|
- } else if strings.Contains(v.Keyword, " ") {
|
|
|
- for _, vk := range strings.Split(v.Keyword, " ") {
|
|
|
- //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
|
|
|
- if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vk))) == 1 {
|
|
|
- queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
- shouldKeys := fmt.Sprintf(multiMatch, "\""+vk+"\"", "\""+queryItem+"\"")
|
|
|
- should = append(should, shouldKeys)
|
|
|
- } else {
|
|
|
- should = append(should, fmt.Sprintf(multiMatchNew, "\""+vk+"\""))
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
|
|
|
- if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(v.Keyword))) == 1 {
|
|
|
- queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
- shouldKeys := fmt.Sprintf(multiMatch, "\""+v.Keyword+"\"", "\""+queryItem+"\"")
|
|
|
- should = append(should, shouldKeys)
|
|
|
- } else {
|
|
|
- should = append(should, fmt.Sprintf(multiMatchNew, "\""+v.Keyword+"\""))
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //附加词
|
|
|
- for _, vv := range v.Appended {
|
|
|
- should = append(should, fmt.Sprintf(multiMatchNew, "\""+vv+"\""))
|
|
|
- }
|
|
|
-
|
|
|
- //排除词
|
|
|
- for _, vv := range v.Exclude {
|
|
|
- //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
|
|
|
- if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vv))) == 1 {
|
|
|
- queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
- shouldKeys := fmt.Sprintf(multiMatch, "\""+vv+"\"", "\""+queryItem+"\"")
|
|
|
- should = append(should, shouldKeys)
|
|
|
- } else {
|
|
|
- mustNot = append(mustNot, fmt.Sprintf(multiMatchNew, "\""+vv+"\""))
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //添加
|
|
|
- if len(should) > 0 {
|
|
|
- notStr := ""
|
|
|
- if len(mustNot) > 0 {
|
|
|
- notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(mustNot, ","))
|
|
|
- }
|
|
|
- bools = append(bools, fmt.Sprintf(queryBoolMustAnd, strings.Join(should, ","), notStr))
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //采购单位联系方式
|
|
|
- if bsp.HasBuyerTel != "" {
|
|
|
- if bsp.HasBuyerTel == "y" {
|
|
|
- mustNot = append(mustNot, fmt.Sprintf(queryMissing, "buyertel"))
|
|
|
- } else {
|
|
|
- musts = append(musts, fmt.Sprintf(queryMissing, "buyertel"))
|
|
|
- }
|
|
|
- }
|
|
|
- //中标企业联系方式
|
|
|
- if bsp.HasWinnerTel != "" {
|
|
|
- if bsp.HasWinnerTel == "y" {
|
|
|
- mustNot = append(mustNot, fmt.Sprintf(queryMissing, "winnertel"))
|
|
|
- } else {
|
|
|
- musts = append(musts, fmt.Sprintf(queryMissing, "winnertel"))
|
|
|
- }
|
|
|
- }
|
|
|
- //搜索范围是否只有附件
|
|
|
- //搜索范围只选择附件,是否有附件条件无效;
|
|
|
- var isFileSearch = strings.ReplaceAll(selectType, ",", "\",\"") == "filetext"
|
|
|
- if !isFileSearch && bsp.FileExists != "" {
|
|
|
- if bsp.FileExists == "1" { //有附件
|
|
|
- mustNot = append(mustNot, fmt.Sprintf(queryMissing, "isValidFile"))
|
|
|
- musts = append(musts, fmt.Sprintf(queryBoolMustTerm, 1))
|
|
|
- } else if bsp.FileExists == "-1" { //无附件
|
|
|
- musts = append(musts, fmt.Sprintf(queryMissing, "isValidFile"))
|
|
|
- }
|
|
|
- }
|
|
|
- qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(mustNot, ","), strings.Join(bools, ","), boolsNum)
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
-// DetailFileORTitle 包含正文或 附件 不包含标题
|
|
|
-func (s *SearchQuery) DetailFileORTitle(findFields string) bool {
|
|
|
- return (strings.Contains(findFields, "detail") || strings.Contains(findFields, "filetext")) && !strings.Contains(findFields, "title")
|
|
|
-}
|
|
|
-
|
|
|
-// DetailANDTitle 包含正文包含标题
|
|
|
-func (s *SearchQuery) DetailANDTitle(findFields string) bool {
|
|
|
- return strings.Contains(findFields, "detail") && strings.Contains(findFields, "title")
|
|
|
-}
|