|
@@ -19,6 +19,19 @@ import (
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ SearchModeAccurate = 0 // 搜索模式:0:精准搜索;
|
|
|
+ SearchModeFuzzy = 1 // 搜索模式:1:模糊搜索
|
|
|
+ WordsModeAnd = 0 // 搜索关键词模式;默认0:包含所有
|
|
|
+ WordsModeOr = 1 // 搜索关键词模式;1:包含任意
|
|
|
+ SearchGroupAll = 0 // 搜索分组:默认0:全部;
|
|
|
+ SearchGroupBidding = 1 // 搜索分组:1:招标采购公告;2:超前项目
|
|
|
+ SearchGroupLeadingProject = 2 // 搜索分组:1:招标采购公告;2:超前项目
|
|
|
+ DefaultTopTypes = "拟建项目,采购意向,招标预告,招标公告,招标结果,招标信用信息"
|
|
|
+ TopTypesBidding = "招标预告,招标公告,招标结果,招标信用信息"
|
|
|
+ TopTypesLeadingProject = "拟建项目,采购意向"
|
|
|
+)
|
|
|
+
|
|
|
/*筛选条件--关键词*/
|
|
|
type KeyWord struct {
|
|
|
Keyword string `json:"keyword"` //关键词
|
|
@@ -52,6 +65,9 @@ type SieveCondition struct {
|
|
|
FileExists string `json:"fileExists"` //是否有附件
|
|
|
SearchTypeSwitch bool `json:"searchTypeSwitch"` //是否开启 正文 标题同时搜索只搜正文的开关
|
|
|
BidField string `json:"bid_field"` // 领域化数据 0101-医疗行业
|
|
|
+ SearchGroup int `json:"searchGroup"` // 搜索分组:默认0:全部;1:招标采购公告;2:超前项目
|
|
|
+ SearchMode int `json:"searchMode"` // 搜索模式:0:精准搜索;1:模糊搜索
|
|
|
+ WordsMode int `json:"wordsMode"` // 搜索关键词模式;默认0:包含所有,1:包含任意
|
|
|
}
|
|
|
|
|
|
const (
|
|
@@ -102,6 +118,7 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
query_missing := `{"constant_score":{"filter":{"missing":{"field":"%s"}}}}`
|
|
|
query_bool_must_term := `{"bool": {"must": [{ "term": {"isValidFile": %d }}]}}`
|
|
|
query_bool_must_term_bidField := `{"bool": {"must": [{ "term": {"bid_field": "%s" }}]}}` // 领域化数据类型
|
|
|
+
|
|
|
gte := `"gte": %s`
|
|
|
lte := `"lte": %s`
|
|
|
|
|
@@ -173,12 +190,20 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
}
|
|
|
timequery += `}}}`
|
|
|
musts = append(musts, timequery)
|
|
|
-
|
|
|
+ if scd.Subtype == "" {
|
|
|
+ if scd.SearchGroup == SearchGroupAll {
|
|
|
+ scd.Subtype = DefaultTopTypes
|
|
|
+ }
|
|
|
+ if scd.SearchGroup == SearchGroupBidding { // 搜索分组处理 招标采购公告 超前项目
|
|
|
+ scd.Subtype = TopTypesBidding
|
|
|
+ } else if scd.SearchGroup == SearchGroupLeadingProject {
|
|
|
+ scd.Subtype = TopTypesLeadingProject
|
|
|
+ }
|
|
|
+ }
|
|
|
if scd.Subtype != "" {
|
|
|
var subquery string
|
|
|
var topTypes []string
|
|
|
var subTypes []string
|
|
|
-
|
|
|
for _, v := range strings.Split(scd.Subtype, ",") {
|
|
|
if v1, ok := topType[v]; ok {
|
|
|
topTypes = append(topTypes, fmt.Sprintf(`"%s"`, v1))
|
|
@@ -281,6 +306,7 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
for _, v := range scd.Keyword {
|
|
|
shoulds := []string{}
|
|
|
must_not := []string{}
|
|
|
+ keysShoulds := []string{}
|
|
|
if v.Keyword != "" {
|
|
|
if strings.Contains(v.Keyword, "+") {
|
|
|
for _, vk := range strings.Split(v.Keyword, "+") {
|
|
@@ -288,9 +314,9 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
if scd.Comeinfrom == "supersearchPage" && DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vk))) == 1 {
|
|
|
queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
shouldsKey := fmt.Sprintf(multi_match, "\""+vk+"\"", "\""+queryItem+"\"")
|
|
|
- shoulds = append(shoulds, shouldsKey)
|
|
|
+ keysShoulds = append(keysShoulds, shouldsKey)
|
|
|
} else {
|
|
|
- shoulds = append(shoulds, fmt.Sprintf(multi_match_new, "\""+vk+"\""))
|
|
|
+ keysShoulds = append(keysShoulds, fmt.Sprintf(multi_match_new, "\""+vk+"\""))
|
|
|
}
|
|
|
}
|
|
|
} else if strings.Contains(v.Keyword, " ") {
|
|
@@ -299,9 +325,9 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
if scd.Comeinfrom == "supersearchPage" && DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vk))) == 1 {
|
|
|
queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
shouldsKey := fmt.Sprintf(multi_match, "\""+vk+"\"", "\""+queryItem+"\"")
|
|
|
- shoulds = append(shoulds, shouldsKey)
|
|
|
+ keysShoulds = append(keysShoulds, shouldsKey)
|
|
|
} else {
|
|
|
- shoulds = append(shoulds, fmt.Sprintf(multi_match_new, "\""+vk+"\""))
|
|
|
+ keysShoulds = append(keysShoulds, fmt.Sprintf(multi_match_new, "\""+vk+"\""))
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
@@ -309,11 +335,13 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
if scd.Comeinfrom == "supersearchPage" && DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(v.Keyword))) == 1 {
|
|
|
queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
|
|
|
shouldsKey := fmt.Sprintf(multi_match, "\""+v.Keyword+"\"", "\""+queryItem+"\"")
|
|
|
- shoulds = append(shoulds, shouldsKey)
|
|
|
+ keysShoulds = append(keysShoulds, shouldsKey)
|
|
|
} else {
|
|
|
- shoulds = append(shoulds, fmt.Sprintf(multi_match_new, "\""+v.Keyword+"\""))
|
|
|
+ keysShoulds = append(keysShoulds, fmt.Sprintf(multi_match_new, "\""+v.Keyword+"\""))
|
|
|
}
|
|
|
}
|
|
|
+ // 单个关键词分词后都包含
|
|
|
+ shoulds = append(shoulds, fmt.Sprintf(query_bool_must_and, strings.Join(keysShoulds, ","), ""))
|
|
|
}
|
|
|
|
|
|
//附加词
|
|
@@ -339,7 +367,11 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
if len(must_not) > 0 {
|
|
|
notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
|
|
|
}
|
|
|
- bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
|
|
|
+ if scd.WordsMode == WordsModeOr { // 包含任意
|
|
|
+ bools = append(bools, fmt.Sprintf(query_bool_should, strings.Join(shoulds, ","), notStr))
|
|
|
+ } else {
|
|
|
+ bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -371,9 +403,7 @@ func getDataExportSql(scd *SieveCondition) string {
|
|
|
}
|
|
|
// 如果是领域化数据则需要加标签
|
|
|
if scd.BidField != "" {
|
|
|
-
|
|
|
musts = append(musts, fmt.Sprintf(query_bool_must_term_bidField, scd.BidField))
|
|
|
-
|
|
|
}
|
|
|
qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(must_not, ","), strings.Join(bools, ","), boolsNum)
|
|
|
return qstr
|
|
@@ -412,6 +442,9 @@ func GetSqlObjFromId(mongo mg.MongodbSim, _id string) *SieveCondition {
|
|
|
FileExists: qutil.ObjToString((*query)["fileExists"]),
|
|
|
SearchTypeSwitch: searchTypeSwitch,
|
|
|
BidField: qutil.ObjToString((*query)["bid_field"]), // 领域化数据
|
|
|
+ SearchGroup: qutil.IntAll((*query)["searchGroup"]), //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
|
|
|
+ SearchMode: qutil.IntAll((*query)["searchMode"]), // 搜索模式:0:精准搜索;1:模糊搜索
|
|
|
+ WordsMode: qutil.IntAll((*query)["wordsMode"]), // 搜索关键词模式;默认0:包含所有,1:包含任意
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -427,37 +460,30 @@ func GetDataExportSearchCountByScdId(sim, bid mg.MongodbSim, biddingName, elasti
|
|
|
}
|
|
|
|
|
|
func GetDataExportSearchCountBySieveCondition(scd *SieveCondition, elasticAddress string) (count int) {
|
|
|
- qstr := getDataExportSql(scd)
|
|
|
- if isNullSearch(scd) {
|
|
|
- return -1 //程序端返回最大值
|
|
|
+ if scd.SearchMode == SearchModeAccurate {
|
|
|
+ qstr := getDataExportSql(scd)
|
|
|
+ if isNullSearch(scd) {
|
|
|
+ return -1 //程序端返回最大值
|
|
|
+ }
|
|
|
+ log.Printf("GetDataExportSearchCountUseId-%s-sql:%s\n", scd.Id, qstr)
|
|
|
+ count = int(elastic.Count(INDEX, TYPE, qstr))
|
|
|
}
|
|
|
- log.Printf("GetDataExportSearchCountUseId-%s-sql:%s\n", scd.Id, qstr)
|
|
|
- count = int(elastic.Count(INDEX, TYPE, qstr))
|
|
|
+ // 依据用户选择的搜索模式和搜索范围进行匹配,即不限制只能匹配标题,且不限制最多展示100条、针对输入的单个关键词分词后需要都包含
|
|
|
//超级搜索一致的检索(防止数据导出和超级搜索数据量不一致)
|
|
|
- if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) {
|
|
|
+ if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) && scd.SearchMode == SearchModeFuzzy {
|
|
|
if len(scd.Keyword) != 0 {
|
|
|
searchTextSize := 0
|
|
|
if len(scd.Keyword) > 0 {
|
|
|
searchTextSize = len([]rune(scd.Keyword[0].Keyword))
|
|
|
}
|
|
|
- if searchTextSize > 3 && count < 50 {
|
|
|
- if strings.Index(scd.SelectType, "title") > -1 {
|
|
|
- var res *[]map[string]interface{}
|
|
|
- if count > 0 {
|
|
|
- res = doSearch(qstr, 0, count, "")
|
|
|
- }
|
|
|
- if secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", elasticAddress); secondKWS != "" {
|
|
|
- scd.Keyword[0].Keyword = secondKWS
|
|
|
- scd.SelectType = "title"
|
|
|
- qstr = getDataExportSql(scd)
|
|
|
- res2 := doSearch(qstr, 0, 100, "")
|
|
|
- result := len(*delRepeatMapArr(res, res2))
|
|
|
- if result > 100 {
|
|
|
- result = 100
|
|
|
- }
|
|
|
- log.Printf("GetDataExportSearchCountUseId-%s-count:%d-分词-sql:%s\n", scd.Id, result, qstr)
|
|
|
- return result
|
|
|
- }
|
|
|
+ if searchTextSize > 3 {
|
|
|
+ if secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", elasticAddress); secondKWS != "" {
|
|
|
+ scd.Keyword[0].Keyword = secondKWS
|
|
|
+ //scd.SelectType = "title"
|
|
|
+ qstr := getDataExportSql(scd)
|
|
|
+ count = int(elastic.Count(INDEX, TYPE, qstr))
|
|
|
+ log.Printf("GetDataExportSearchCountUseId-%s-count:%d-分词-sql:%s\n", scd.Id, count, qstr)
|
|
|
+ return count
|
|
|
}
|
|
|
}
|
|
|
return
|
|
@@ -673,33 +699,29 @@ func GetDataExportSearchResult(bid mg.MongodbSim, bidMgoDBName, elasticAddress s
|
|
|
return idSelectDates, idSelectErr
|
|
|
}
|
|
|
selectType := scd.SelectType
|
|
|
- //获取查询语句
|
|
|
- qstr := getDataExportSql(scd)
|
|
|
- log.Printf("GetDataExportSearchResult-%s-sql:%s\n", scd.Id, qstr)
|
|
|
-
|
|
|
- //数据导出数据查询
|
|
|
- res := doSearchByBatch(qstr, dataType, checkCount, fmt.Sprintf("%s-%s", "GetDataExportSearchResult", scd.Id))
|
|
|
+ var qstr string
|
|
|
+ var res []map[string]interface{}
|
|
|
+ if scd.SearchMode == SearchModeAccurate { // 搜索模式为精确查找
|
|
|
+ //获取查询语句
|
|
|
+ qstr = getDataExportSql(scd)
|
|
|
+ log.Printf("GetDataExportSearchResult-%s-sql:%s\n", scd.Id, qstr)
|
|
|
+ //数据导出数据查询
|
|
|
+ res = doSearchByBatch(qstr, dataType, checkCount, fmt.Sprintf("%s-%s", "GetDataExportSearchResult", scd.Id))
|
|
|
+ }
|
|
|
//超级搜索一致的检索(防止数据导出和超级搜索数据量不一致)
|
|
|
- if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) && len(scd.SelectIds) == 0 {
|
|
|
+ if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) && len(scd.SelectIds) == 0 && scd.SearchMode == SearchModeFuzzy {
|
|
|
if len(scd.Keyword) != 0 {
|
|
|
- num := len(res)
|
|
|
searchTextSize := 0
|
|
|
if len(scd.Keyword) > 0 {
|
|
|
searchTextSize = len([]rune(scd.Keyword[0].Keyword))
|
|
|
}
|
|
|
- if searchTextSize > 3 && num < 50 {
|
|
|
- if strings.Index(scd.SelectType, "title") > -1 {
|
|
|
- if secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", elasticAddress); secondKWS != "" {
|
|
|
- scd.Keyword[0].Keyword = secondKWS
|
|
|
- scd.SelectType = "title"
|
|
|
- qstr = getDataExportSql(scd)
|
|
|
- log.Printf("GetDataExportSearchResult-%s-分词查询-sql:%s\n", scd.Id, qstr)
|
|
|
- res2 := doSearch(qstr, 0, 100, "")
|
|
|
- res = *delRepeatMapArr(&res, res2)
|
|
|
- if len(res) > 100 {
|
|
|
- res = res[:100]
|
|
|
- }
|
|
|
- }
|
|
|
+ if searchTextSize > 3 {
|
|
|
+ if secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", elasticAddress); secondKWS != "" {
|
|
|
+ scd.Keyword[0].Keyword = secondKWS
|
|
|
+ //scd.SelectType = "title"
|
|
|
+ qstr = getDataExportSql(scd)
|
|
|
+ log.Printf("GetDataExportSearchResult-%s-分词查询-sql:%s\n", scd.Id, qstr)
|
|
|
+ res = doSearchByBatch(qstr, dataType, checkCount, fmt.Sprintf("%s-%s", "GetDataExportSearchResult", scd.Id))
|
|
|
}
|
|
|
}
|
|
|
}
|