From f1503b6490276aa06869daf27064d9bd5ddca4ed Mon Sep 17 00:00:00 2001 From: 97694731 <97694731@qq.com> Date: Tue, 31 Mar 2026 10:01:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- es/es_search.go | 121 +++++++++++++++++++++++++++++++++++++++++++++--- main.go | 4 +- service/book.go | 47 +++++++++++++++---- 3 files changed, 155 insertions(+), 17 deletions(-) diff --git a/es/es_search.go b/es/es_search.go index c640c63..1e4d250 100644 --- a/es/es_search.go +++ b/es/es_search.go @@ -25,7 +25,7 @@ import ( "github.com/elastic/go-elasticsearch/v8/esapi" ) -const ESIndex = "books-from-mysql-v3" +const ESIndex = "books-from-mysql-v2" // ESBookResponse 用于返回给Java客户端的格式,ID为简单的int64 type ESBookResponse struct { @@ -1545,7 +1545,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in "bookName": "book_name", "bookPic": "book_pic", "publication_times": "publication_time", - "isSuit": "is_suit", + //"isSuit": "is_suit", } // ===== saleSelect 对应字段映射 ===== @@ -1588,7 +1588,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in continue } // 不作为查询条件的字段 - if key == "page" || key == "pageSize" || key == "per_page" || key == "saleSelect" || key == "picType" || key == "shopType" { + if key == "page" || key == "pageSize" || key == "per_page" || key == "saleSelect" || key == "picType" || key == "shopType" || key == "isSuit" || key == "is_return" { continue } @@ -1610,7 +1610,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in key = nk } - // ===== is_suit ===== + //TODO ===== is_suit ===== if key == "is_suit" { fmt.Printf("[DEBUG] is_suit val=%q\n", val) if num, err := strconv.Atoi(val); err == nil { @@ -1625,7 +1625,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in continue } - // ===== is_return ===== + //TODO ===== is_return ===== if key == "is_return" { fmt.Printf("[DEBUG] is_return val=%q\n", val) if num, err := strconv.Atoi(val); err == nil { @@ -1678,6 +1678,35 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in "is_filter": pattern, }, } + if val == "2" { + cond = map[string]interface{}{ + "bool": map[string]interface{}{ + "should": []map[string]interface{}{ + // 情况 1: is_filter 字段null + { + "bool": map[string]interface{}{ + "must_not": []map[string]interface{}{ + {"exists": map[string]interface{}{"field": "is_filter"}}, + }, + }, + }, + // 情况 2: is_filter 空串 + { + "term": map[string]interface{}{ + "is_filter": "", + }, + }, + // 情况 3: is_filter 字段存在且匹配 wildcard 模式 + { + "wildcard": map[string]interface{}{ + "is_filter": pattern, + }, + }, + }, + "minimum_should_match": 1, + }, + } + } must = append(must, cond) fmt.Printf("[DEBUG] must += %v\n", cond) @@ -1812,6 +1841,32 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in }, }, } + if minVal == 0 { + cond = map[string]interface{}{ + "bool": map[string]interface{}{ + "should": []map[string]interface{}{ + // 情况 1: buy_counts 字段不存在或为 null + { + "bool": map[string]interface{}{ + "must_not": []map[string]interface{}{ + {"exists": map[string]interface{}{"field": "buy_counts"}}, + }, + }, + }, + // 情况 2: buy_counts 在范围内 + { + "range": map[string]interface{}{ + "buy_counts": map[string]interface{}{ + "gte": minVal, + "lte": maxVal, + }, + }, + }, + }, + "minimum_should_match": 1, + }, + } + } must = append(must, cond) fmt.Printf("[DEBUG] must += %v\n", cond) continue @@ -1837,6 +1892,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in if len(parts) == 2 { minVal, _ := strconv.Atoi(parts[0]) maxVal, _ := strconv.Atoi(parts[1]) + cond := map[string]interface{}{ "range": map[string]interface{}{ "total_sale": map[string]interface{}{ @@ -1845,6 +1901,32 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in }, }, } + if minVal == 0 { + cond = map[string]interface{}{ + "bool": map[string]interface{}{ + "should": []map[string]interface{}{ + // 情况 1: total_sale 字段不存在或为 null + { + "bool": map[string]interface{}{ + "must_not": []map[string]interface{}{ + {"exists": map[string]interface{}{"field": "total_sale"}}, + }, + }, + }, + // 情况 2: total_sale 在范围内 + { + "range": map[string]interface{}{ + "total_sale": map[string]interface{}{ + "gte": minVal, + "lte": maxVal, + }, + }, + }, + }, + "minimum_should_match": 1, + }, + } + } must = append(must, cond) fmt.Printf("[DEBUG] must += %v\n", cond) continue @@ -1870,6 +1952,32 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in }, }, } + if minVal == 0 { + cond = map[string]interface{}{ + "bool": map[string]interface{}{ + "should": []map[string]interface{}{ + // 情况 1: total_sale 字段不存在或为 null + { + "bool": map[string]interface{}{ + "must_not": []map[string]interface{}{ + {"exists": map[string]interface{}{"field": "total_sale"}}, + }, + }, + }, + // 情况 2: total_sale 在范围内 + { + "range": map[string]interface{}{ + key: map[string]interface{}{ + "gte": minVal, + "lte": maxVal, + }, + }, + }, + }, + "minimum_should_match": 1, + }, + } + } must = append(must, cond) fmt.Printf("[DEBUG] must += %v\n", cond) continue @@ -1902,6 +2010,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in continue } + fmt.Println("key--------------", key) // ===== 默认前缀匹配 ===== cond := map[string]interface{}{ "prefix": map[string]interface{}{key: val}, @@ -1972,7 +2081,7 @@ func (svc *ESSearchService) BatchGetBookBaseInfoES(c *gin.Context) ([]ESBook, in res, duration, err := monitoredES.Search(context.Background(), &req) - fmt.Printf("[DEBUG] ES Query Response:\n%s\n", res) + //fmt.Printf("[DEBUG] ES Query Response:\n%s\n", res) fmt.Printf("[DEBUG] ES 查询耗时:%dms\n", duration.Milliseconds()) if err != nil { diff --git a/main.go b/main.go index 620de71..e510fa4 100644 --- a/main.go +++ b/main.go @@ -185,9 +185,9 @@ func main() { //) /** ES2 本地测试 **/ esClient, err := es.NewESClient( - []string{"http://36.212.1.63:9200"}, + []string{"https://103.236.91.138:9200"}, "elastic", - "zDzSXel3PFwx9=6Ybmqv", + "7AYdoW=mn3yHZ*3A=Z1x", ) if err != nil { diff --git a/service/book.go b/service/book.go index d9a3549..1a9ae9e 100644 --- a/service/book.go +++ b/service/book.go @@ -11,8 +11,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/elastic/go-elasticsearch/v8/esapi" - jsoniter "github.com/json-iterator/go" "io" "log" "mime/multipart" @@ -20,6 +18,9 @@ import ( "strconv" "strings" "time" + + "github.com/elastic/go-elasticsearch/v8/esapi" + jsoniter "github.com/json-iterator/go" ) // BookService 图书搜索服务 @@ -881,7 +882,7 @@ func (svc *BookService) SyncRedisByISBN(isbn string, act string) error { if book.PublicationTime != "" && book.PublicationTime != "0" { publicationTimeIn64, err := strconv.ParseInt(book.PublicationTime, 10, 64) if err == nil { - redisBookInfo.PublicationDate = time.Unix(publicationTimeIn64, 0).Format("2006-01") + redisBookInfo.PublicationDate = time.Unix(publicationTimeIn64+5364000000, 0).Format("2006-01") } } if book.BindingLayout != "" { @@ -1420,12 +1421,40 @@ func (svc *BookService) buildBuyCountsCondition(builder *ESQueryBuilder, buyCoun if len(parts) == 2 { minVal, _ := strconv.Atoi(parts[0]) maxVal, _ := strconv.Atoi(parts[1]) - builder.AddQuery(&QueryCondition{ - Field: saleField, - Type: "range", - GTE: minVal, - LTE: maxVal, - }) + // 如果查询范围包含 0(0-999999),需要同时匹配 null 值 + if minVal == 0 { + // 使用 bool should 查询:匹配范围内值 OR 字段为 null/不存在 + rangeQuery := map[string]interface{}{ + "range": map[string]interface{}{ + "buy_counts": map[string]interface{}{ + "gte": minVal, + "lte": maxVal, + }, + }, + } + + nullQuery := map[string]interface{}{ + "bool": map[string]interface{}{ + "must_not": []map[string]interface{}{ + { + "exists": map[string]interface{}{ + "field": "buy_counts", + }, + }, + }, + }, + } + + builder.AddBoolQuery("should", []map[string]interface{}{rangeQuery, nullQuery}) + } else { + // 普通范围查询,不包含 null 值 + builder.AddQuery(&QueryCondition{ + Field: saleField, + Type: "range", + GTE: minVal, + LTE: maxVal, + }) + } return }