需求 业务需求,查询在指定时间段过生日的人.如 2-28 到 9-15 之间过生日的人
解决方案 业务存储有生日的毫秒级时间戳 ‘birthday’
mysql 1 2 3 select * from user where DATE_FORMAT(FROM_UNIXTIME(birthday/ 1000 ),'%m-%d' ) BETWEEN '02-28' AND '09-15' ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 SELECT * FROM user WHERE DATE_ADD(FROM_UNIXTIME(birthday/ 1000 ), INTERVAL YEAR (CURDATE())- YEAR (FROM_UNIXTIME(birthday/ 1000 )) + IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(FROM_UNIXTIME(birthday/ 1000 )),1 ,0 ) YEAR ) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY ); SELECT * FROM user WHERE DATE_ADD(FROM_UNIXTIME(birthday/ 1000 ), INTERVAL YEAR (FROM_UNIXTIME(1701662559000 / 1000 ))- YEAR (FROM_UNIXTIME(birthday/ 1000 )) + IF(DAYOFYEAR(FROM_UNIXTIME(1701662559000 / 1000 )) > DAYOFYEAR(FROM_UNIXTIME(birthday/ 1000 )),1 ,0 ) YEAR ) BETWEEN FROM_UNIXTIME(1701662559000 / 1000 ) AND FROM_UNIXTIME(1704340959000 / 1000 );
es 方案一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 GET user / _search{ "query": { "bool": { "filter": [ { "exists": {"field": "birthday"} }, { "script": { "script": { "source": """ def date = Instant.ofEpochMilli(doc['birthday'].value).atZone(ZoneId.of("Asia/ Shanghai")); def month = date.getMonthValue(); def day = date.getDayOfMonth(); return (month == 2 && day >= 28) || (month > 2 && month < 9) || (month == 9 && day <= 15); """ } } }, { "range": { "birthday": { "gt": 0 } } } ] } } }
方案二 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 GET user / _search{ "query": { "bool": { "filter": [ { "exists": {"field": "birthday"} }, { "script": { "script": { "source": """ def start=1701662559000L; def end=1704340959000L; def startTime = Instant.ofEpochMilli(start).atZone(ZoneId.of("Asia/ Shanghai")); def endTime= Instant.ofEpochMilli(end).atZone(ZoneId.of("Asia/ Shanghai")); def birthdayTime = Instant.ofEpochMilli(doc['birthday'].value).atZone(ZoneId.of("Asia/ Shanghai")); def birthdayDate = birthdayTime.toLocalDate(); def startTimeDate=startTime.toLocalDate(); def endTimeDate=endTime.toLocalDate(); def a=LocalDate.of(startTimeDate.getYear(), birthdayDate.getMonthValue(),birthdayDate.getDayOfMonth()) .atStartOfDay().atZone(ZoneId.of("Asia/ Shanghai")); def b=LocalDate.of(endTimeDate.getYear(), birthdayDate.getMonthValue(),birthdayDate.getDayOfMonth()) .atStartOfDay().atZone(ZoneId.of("Asia/ Shanghai")); return (a.isAfter(startTime) && a.isBefore(endTime)) || (b.isAfter(startTime) && b.isBefore(endTime)); """ } } }, { "range": { "birthday": { "gt": 0 } } } ] } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 long start=1706517776000L ;long end=1714809776000L ;ZonedDateTime startTime = Instant.ofEpochMilli(start).atZone(ZoneId.of("Asia/Shanghai" ));ZonedDateTime endTime= Instant.ofEpochMilli(end).atZone(ZoneId.of("Asia/Shanghai" )); ZonedDateTime birthdayTime = Instant.ofEpochMilli(228096000000L ).atZone(ZoneId.of("Asia/Shanghai" ));LocalDate birthdayDate = birthdayTime.toLocalDate();LocalDate startTimeDate=startTime.toLocalDate(); LocalDate endTimeDate=endTime.toLocalDate(); ZonedDateTime a=LocalDate.of(startTimeDate.getYear(), birthdayDate.getMonthValue(),birthdayDate.getDayOfMonth()) .atStartOfDay().atZone(ZoneId.of("Asia/Shanghai" )); ZonedDateTime b=LocalDate.of(endTimeDate.getYear(), birthdayDate.getMonthValue(),birthdayDate.getDayOfMonth()) .atStartOfDay().atZone(ZoneId.of("Asia/Shanghai" )); return (a.isAfter(startTime) && a.isBefore(endTime))||(b.isAfter(startTime) && b.isBefore(endTime));
使用go的package(“github.com/olivere/elastic/v7”)实现上述查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 boolQuery := elastic.NewBoolQuery().Filter( elastic.NewRangeQuery("birthday" ).Gt(0 ), elastic.NewExistsQuery("birthday" ), elastic.NewScriptQuery(elastic.NewScript(fmt.Sprintf( `def start=%dL; def end=%dL; def startTime = Instant.ofEpochMilli(start); def endTime= Instant.ofEpochMilli(end); def birthdayTime = Instant.ofEpochMilli(1702662559000L); def birthdayDate = birthdayTime.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate(); def startTimeDate=startTime.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate(); def endTimeDate=endTime.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate(); def a=LocalDate.of(startTimeDate.getYear(), birthdayDate.getMonthValue(),birthdayDate.getDayOfMonth()) .atStartOfDay().atZone(ZoneId.of("Asia/Shanghai")).toInstant(); def b=LocalDate.of(endTimeDate.getYear(), birthdayDate.getMonthValue(),birthdayDate.getDayOfMonth()) .atStartOfDay().atZone(ZoneId.of("Asia/Shanghai")).toInstant(); return (a.isAfter(startTime) && a.isBefore(endTime))||(b.isAfter(startTime) && b.isBefore(endTime));` , birthdayStart, birthdayEnd)), )) searchResult, err := esClient.Search().Index("user" ).Query(boolQuery).Do(context.Background()) if err != nil { fmt.Printf("Error executing search: %v\n" , err) return } for _, hit := range searchResult.Hits.Hits { fmt.Printf("Document ID: %s\n" , hit.Id) }
参考
Be the first person to leave a comment!