package es import ( "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/bxcore" "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/entity" IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/init" "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/util" "fmt" "strconv" "strings" "time" MC "app.yhyue.com/moapp/jybase/common" elastic "app.yhyue.com/moapp/jybase/es" "log" ) // GetSearchQuery 整理关键词等查询条件 func GetSearchQuery(in *bxcore.SearchReq, mustQuery string) (qstr string) { var ( //搜索范围是否只有附件 //搜索范围只选择附件,是否有附件条件无效; isFileSearch = in.SelectType == "filetext" wordsMusts, wordsShould, musts, mustNot []string findFields string selectTypeArr = strings.Split(in.SelectType, ",") isLogin = in.UserId != "" ) if selectTypeArr == nil || len(selectTypeArr) == 0 { findFields = `"title"` } else { findFields = fmt.Sprintf(`"%s"`, strings.Join(selectTypeArr, "\",\"")) } switchBool := strings.Contains(findFields, "detail") && strings.Contains(findFields, "title") && IC.C.SearchTypeSwitch if mustQuery != "" { musts = append(musts, mustQuery) } //采购单位 if in.Buyer != "" { musts = append(musts, util.GetMatchArrSql("buyer.mbuyer", strings.Split(in.Buyer, ",")...)) } //中标单位 if in.Winner != "" { musts = append(musts, util.GetMatchArrSql("s_winner.mwinner", strings.Split(in.Winner, ",")...)) } //代理机构 if in.Agency != "" { musts = append(musts, util.GetMatchArrSql("agency.magency", strings.Split(in.Agency, ",")...)) } //此时关键词中间有IC.C.JYKeyMark进行隔离 if in.KeyWords != "" { var ( keyWordsMusts []string ) for _, v := range strings.Split(in.KeyWords, IC.C.JYKeyMark) { if elastic.ReplaceYH(v) == "" { continue } //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题 //detail 正文不支持单字查询 if len([]rune(elastic.ReplaceYH(v))) == 1 && DetailFileORTitle(findFields) { findFields += `,"title"` } else if switchBool && len([]rune(elastic.ReplaceYH(v))) > 1 { //标题 全文搜索 搜索类型开关打开 默认搜索全文;(全文包含标题)(单字排除) if strings.Contains(findFields, `"title",`) { findFields = strings.Replace(findFields, `"title",`, ``, -1) } else if strings.Contains(findFields, `,"title"`) { findFields = strings.Replace(findFields, `,"title"`, ``, -1) } } keyWordsMusts = append(keyWordsMusts, fmt.Sprintf(fmt.Sprintf(MultiMatch, "%s", findFields), elastic.ReplaceYH(v))) } //搜索关键词模式;默认0:包含所有,1:包含任意 if in.WordsMode == 1 { wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(keyWordsMusts, ","))) } else { wordsMusts = append(wordsMusts, keyWordsMusts...) } } //附加词 if in.AdditionalWords != "" { //多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词 var ( addWordsMusts []string ) for _, aws := range strings.Split(in.AdditionalWords, ",") { var ( addWordsMust []string ) for _, v := range strings.Split(aws, IC.C.JYKeyMark) { if elastic.ReplaceYH(v) == "" { continue } //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题 //detail 正文不支持单字查询 if len([]rune(elastic.ReplaceYH(v))) == 1 && DetailFileORTitle(findFields) { findFields += `,"title"` } else if switchBool && len([]rune(elastic.ReplaceYH(v))) > 1 { //标题 全文搜索 搜索类型开关打开 默认搜索全文;(全文包含标题)(单字排除) if strings.Contains(findFields, `"title",`) { findFields = strings.Replace(findFields, `"title",`, ``, -1) } else if strings.Contains(findFields, `,"title"`) { findFields = strings.Replace(findFields, `,"title"`, ``, -1) } } addWordsMust = append(addWordsMust, fmt.Sprintf(fmt.Sprintf(MultiMatch, "%s", findFields), elastic.ReplaceYH(v))) addWordsMusts = append(addWordsMusts, addWordsMust...) if in.WordsMode == 0 { wordsMusts = append(wordsMusts, addWordsMust...) } addWordsMust = []string{} } //搜索关键词模式;默认0:包含所有,1:包含任意 if in.WordsMode == 1 { wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(addWordsMusts, ","))) addWordsMusts = []string{} } } } //搜索关键词模式;默认0:包含所有,1:包含任意 //包含任意一组 if len(wordsShould) > 0 { musts = append(musts, fmt.Sprintf(QueryBoolShould, strings.Join(wordsShould, ","))) } else if len(wordsMusts) > 0 { musts = append(musts, fmt.Sprintf(elastic.NgramMust, strings.Join(wordsMusts, ","))) } //排除词 if notKey := strings.TrimSpace(in.ExclusionWords); notKey != "" { notKeyMultiMatch := fmt.Sprintf(MultiMatch, "%s", findFields) var notKeyMustNot []string //多组排除词 for _, nks := range strings.Split(notKey, ",") { //单组排除词 空格分割 for _, v := range strings.Split(nks, IC.C.JYKeyMark) { v = strings.TrimSpace(v) if v == "" { continue } if len([]rune(elastic.ReplaceYH(v))) == 1 { //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题 if DetailFileORTitle(findFields) { notKeyMultiMatch = fmt.Sprintf(MultiMatch, "%s", findFields+`,"title"`) } } notKeyMustNot = append(notKeyMustNot, fmt.Sprintf(notKeyMultiMatch, elastic.ReplaceYH(v))) } } mustNot = append(mustNot, fmt.Sprintf(QueryBoolShould, strings.Join(notKeyMustNot, ","))) } //行业 if in.Industry != "" && isLogin { musts = append(musts, fmt.Sprintf(QueryBoolMustA, "s_subscopeclass", `"`+strings.ReplaceAll(in.Industry, ",", `","`)+`"`)) //var ( // topSC []string // topQT bool //) //for _, sv := range strings.Split(in.Industry, ",") { // if strings.Contains(sv, "其他") { // if len(strings.Split(sv, "_")) > 1 { // topSC = append(topSC, strings.Split(sv, "_")[0]) // } else { // topQT = true // } // } //} ////一级行业-其他 //if topQT { // mustNot = append(mustNot, `{"exists": {"field": "s_topscopeclass"}}`) //} //if len(topSC) > 0 { // //二级行业-其他 // musts = append(musts, fmt.Sprintf(queryBoolMustScopeClass, `"`+strings.ReplaceAll(in.Industry, ",", `","`)+`"`, `"`+strings.Join(topSC, `","`)+`"`)) //} else { // musts = append(musts, fmt.Sprintf(QueryBoolMustA, "s_subscopeclass", `"`+strings.ReplaceAll(in.Industry, ",", `","`)+`"`)) //} } //价格 if in.Price != "" && len(strings.Split(in.Price, "-")) > 1 { minPrice, maxPrice := strings.Split(in.Price, "-")[0], strings.Split(in.Price, "-")[1] if minPrice != "" || maxPrice != "" { sq := `` if minPrice != "" { min, _ := strconv.ParseFloat(minPrice, 64) minPrice = fmt.Sprintf("%.0f", min*10000) if minPrice == "0" { minPrice = "" } } if maxPrice != "" { max, _ := strconv.ParseFloat(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 != "" { query_price := fmt.Sprintf(QueryBoolShould, fmt.Sprintf(queryBoolMustBoolShould, sq, sq)) musts = append(musts, query_price) } } } //采购单位联系方式 hasBuyerTel := in.BuyerTel if hasBuyerTel != "" { if hasBuyerTel == "y" { musts = append(musts, fmt.Sprintf(queryExists, "buyertel")) } else { mustNot = append(mustNot, fmt.Sprintf(queryExists, "buyertel")) } } //中标企业联系方式 hasWinnerTel := in.WinnerTel if hasWinnerTel != "" { if hasWinnerTel == "y" { musts = append(musts, fmt.Sprintf(queryExists, "winnertel")) } else { mustNot = append(mustNot, fmt.Sprintf(queryExists, "winnertel")) } } //移动融创 if in.MobileTag != nil && len(in.MobileTag) > 0 && in.IsPay { //仅付费bidding表有此字段 musts = append(musts, fmt.Sprintf(QueryBoolMustA, "mobile_tag", `"`+strings.Join(in.MobileTag, `","`)+`"`)) } if isLogin { //需要登录 //电脑端 物业专版BI if in.BidField == "BIProperty" { if !entity.MobileReg.MatchString(in.UserAgent) { musts = append(musts, fmt.Sprintf(QueryBoolMustA, "tag_topinformation", `"情报_物业"`)) //物业业态 if in.PropertyForm != "" { arr := []string{} for _, v := range strings.Split(in.PropertyForm, ",") { arr = append(arr, fmt.Sprintf(`"%s"`, v)) } musts = append(musts, fmt.Sprintf(QueryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.property_form":[%s]}}`, strings.Join(arr, ",")))) } //业务类型 if in.SubInformation != "" { arr := []string{} for _, v := range strings.Split(in.SubInformation, ",") { arr = append(arr, fmt.Sprintf(`"%s"`, v)) } musts = append(musts, fmt.Sprintf(QueryBoolShould, fmt.Sprintf(`{"terms":{"tag_subinformation":[%s]}}`, strings.Join(arr, ",")))) } //价格区间 if in.Scale != "" { arr := []string{} for _, v := range strings.Split(in.Scale, ",") { arr = append(arr, fmt.Sprintf(`"%s"`, v)) } musts = append(musts, fmt.Sprintf(QueryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.scale":[%s]}}`, strings.Join(arr, ",")))) } //合同周期 if in.Period != "" { arr := []string{} for _, v := range strings.Split(in.Period, ",") { arr = append(arr, fmt.Sprintf(`"%s"`, v)) } musts = append(musts, fmt.Sprintf(QueryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.period":[%s]}}`, strings.Join(arr, ",")))) } //换手率 if in.ChangeHand != 0 { if in.ChangeHand > 0 { //存在 musts = append(musts, `{"range":{"tag_set.wuye.changehand":{"gt":0.3}}}`) } } if in.FileExists != "" { if in.FileExists == "1" { //存在 musts = append(musts, fmt.Sprintf(QueryBoolMustA, "tag_set.wuye.isfile", `"63"`)) } else { //不存在 mustNot = append(mustNot, fmt.Sprintf(queryExists, "tag_set.wuye.isfile")) } } } } else { //附件--非BI fileExists := in.FileExists if !isFileSearch && fileExists != "" { if fileExists == "1" { //有附件 musts = append(musts, fmt.Sprintf(QueryBoolMustTermBool, "isValidFile", true)) } else if fileExists == "-1" { //无附件 mustNot = append(mustNot, fmt.Sprintf(QueryBoolMustTermBool, "isValidFile", true)) } } if in.BidField == "medical" { // 如果是领域化数据则需要加标签 musts = append(musts, fmt.Sprintf(queryBoolMustTermDomain, "0101")) } } } //in.BidField 剑鱼默认招标信息搜索 此参数为空** qstr = fmt.Sprintf(Query, strings.Join(musts, ","), strings.Join(mustNot, ",")) log.Println("qstr:", qstr) return } // GetBidSearchQuery 整理地区、城市、发布时间、信息类型、采购单位类型 查询条件 func GetBidSearchQuery(in *bxcore.SearchReq) string { query := `` //省份 area := in.Province isLogin := in.UserId != "" if area != "" { query += `{"terms":{"area":[` for k, v := range strings.Split(area, ",") { if k > 0 { query += `,` } query += `"` + v + `"` } query += `]}}` } //市--未登录用户不能根据市和地区筛选 city := in.City if city != "" && isLogin { if len(query) > 0 { query += "," } query += `{"terms":{"city":[` for k, v := range strings.Split(city, ",") { if k > 0 { query += `,` } query += `"` + v + `"` } query += `]}}` } district := in.District if district != "" && isLogin { if len(query) > 0 { query += "," } for k, v := range strings.Split(district, ",") { if k > 0 { query += `,` } cityName := strings.Split(v, "_")[0] districtName := strings.Split(v, "_")[1] queryBoolMustAndDistrict := `{"bool":{"must":[{"terms":{"city":["%s"]}},{"terms":{"district":["%s"]}}]}}` query += fmt.Sprintf(queryBoolMustAndDistrict, cityName, districtName) } } if query != "" { query = fmt.Sprintf(QueryBoolShould, query) } //发布时间 publishTime := in.PublishTime if publishTime != "" { startTime, endTime := "", "" now := time.Now() switch publishTime { case "lately-7": startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-7, 0, 0, 0, 0, time.Local).Unix()) case "lately-30": startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-30, 0, 0, 0, 0, time.Local).Unix()) case "thisyear": startTime = fmt.Sprint(time.Date(now.Year()-1, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix()) endTime = fmt.Sprint(now.Unix()) case "threeyear": startTime = fmt.Sprint(time.Date(now.Year()-3, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix()) endTime = fmt.Sprint(now.Unix()) case "fiveyear": startTime = fmt.Sprint(time.Date(now.Year()-5, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix()) endTime = fmt.Sprint(now.Unix()) default: if len(strings.Split(publishTime, "-")) > 1 { startTime = strings.Split(publishTime, "-")[0] endTime = strings.Split(publishTime, "-")[1] //电脑端 时间选择 开始时间当天和结束时间当天相同 if startTime == endTime { et, _ := strconv.ParseInt(endTime, 0, 64) etTime := time.Unix(et, 0) endTime = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Unix()) } } } if startTime != "" || endTime != "" { if len(query) > 0 { query += "," } query += `{"range":{"publishtime":{` if startTime != "" { query += `"gte":` + startTime } if startTime != "" && endTime != "" { query += `,` } if endTime != "" { query += `"lt":` + endTime } query += `}}}` } } //信息类型-二级 subtype := in.Subtype topType := MC.If(in.TopType != "", strings.Split(in.TopType, ","), []string{}).([]string) allType := `` //二级分类 if subtype != "" { var typeInt = 0 allType += `{"terms":{"subtype":[` for k, v := range strings.Split(subtype, ",") { if tType := MC.If(topTypeMap[v] != "" && in.TopType == "", topTypeMap[v], "").(string); tType != "" { topType = append(topType, tType) typeInt += 1 continue } if k > typeInt { allType += `,` } allType += `"` + v + `"` } allType += `]}}` if typeInt == len(strings.Split(subtype, ",")) { allType = `` } } //信息类型 一级分类 log.Println("topType:", topType) if len(topType) > 0 { if allType != "" { allType += "," } allType += `{"terms":{"toptype":[` for k, v := range topType { if k > 0 { allType += `,` } allType += `"` + v + `"` } allType += `]}}` } if allType != "" { if query != "" { query += "," } query += fmt.Sprintf(QueryBoolShould, allType) } //采购单位类型 buyerClass := in.BuyerClass if buyerClass != "" { if len(query) > 0 { query += "," } query += `{"terms":{"buyerclass":[` for k, v := range strings.Split(buyerClass, ",") { if k > 0 { query += `,` } query += `"` + v + `"` } query += `]}}` } //电脑端 物业专版BI if !entity.MobileReg.MatchString(in.UserAgent) { if in.ExpireTime != "" { if len(query) > 0 { query += "," } startTime, endTime := "", "" now := time.Now() if in.ExpireTime == "1" { //本月到期 startTime = fmt.Sprint(now.Unix()) first := time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, time.Local) endTime = fmt.Sprint(first.AddDate(0, 0, 0).Unix()) /* endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, time.Local).Unix())*/ } else if in.ExpireTime == "1-3" { //1-3个月到期 startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+1, now.Day(), 0, 0, 0, 0, time.Local).Unix()) endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+3, now.Day(), 0, 0, 0, 0, time.Local).Unix()) } else if in.ExpireTime == "3-6" { //3-6个月到期 startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+3, now.Day(), 0, 0, 0, 0, time.Local).Unix()) endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+6, now.Day(), 0, 0, 0, 0, time.Local).Unix()) } else if in.ExpireTime == "6-12" { //6-12个月到期 startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+6, now.Day(), 0, 0, 0, 0, time.Local).Unix()) endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+12, now.Day(), 0, 0, 0, 0, time.Local).Unix()) } else if in.ExpireTime == "12" { //12个月以后 startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+12, now.Day(), 0, 0, 0, 0, time.Local).Unix()) } else if len(strings.Split(in.ExpireTime, "_")) > 1 { startTime = strings.Split(in.ExpireTime, "_")[0] endTime = strings.Split(in.ExpireTime, "_")[1] etTime := time.Now() if endTime != "" { et, _ := strconv.ParseInt(endTime, 0, 64) etTime = time.Unix(et, 0) } endTime = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Unix()) } query += `{"range":{"expiredate":{` if startTime != "" { query += `"gte":` + startTime } if startTime != "" && endTime != "" { query += `,` } if endTime != "" { query += `"lt":` + endTime } query += `}}}` } } return query } // DetailFileORTitle 包含正文或 附件 不包含标题 func DetailFileORTitle(findFields string) bool { return (strings.Contains(findFields, `"detail"`) || strings.Contains(findFields, `"filetext"`)) && !strings.Contains(findFields, `"title"`) }