如何在MongoDB中使用Google的Civil.Date包的过滤查询?

xfb7svmp  于 2022-11-03  发布在  Go
关注(0)|答案(2)|浏览(96)

Google的civil包很简单--它的目标是表示一年中的某一天,而不考虑时间或位置。这对于像生日这样的事情很有用,因为世界各地的时间都是一样的--尽管世界各地的时间是不同的。
主结构是:

type Date struct {
    Year  int        // Year (e.g., 2014).
    Month time.Month // Month of the year (January = 1, ...).
    Day   int        // Day of the month, starting at 1.
}

它在MongoDB中被表示为一个具有3个整数值的对象:


# golang definition

occurredOn civil.Date `bson:"occurredOn"`
...

# mongodb definition

occurredOn Object
year       2022
month      4
day        2

如果你想查询的话,这会导致奇怪的结果。例如,我不认为标准的$gt/$lt查询会起作用,因为2022-4-2在字典上大于2022-10-20,但它是一个更早的日期,我相信mongoDB可以在最好的情况下比较对象,但这也增加了查询的内部复杂性。本质上,它是'这比比较两个time.Time的示例要复杂得多。那么最简单的方法是什么呢?

ulydmbyx

ulydmbyx1#

据我所知,有四个边缘案例需要涵盖:

  • 日期相同但年份不同
  • 日期相同但月份不同
  • 相同日期但不同日期
  • 不同年/月/日的某种组合

下面这个函数返回一个mongoDB查询,以检查civil.Date是否严格大于另一个civil.Date

func occurredOnGTQueryTest(date civil.Date) bson.M {
    return bson.M{"$or": bson.A{
        bson.M{"occurredOn.year": bson.M{"$gt": date.Year}}, // happens in the next year

        bson.M{"occurredOn.year": bson.M{"$gte": date.Year},
            "occurredOn.month": bson.M{"$gt": date.Month}}, // happens in the next month

        bson.M{"occurredOn.year": bson.M{"$gte": date.Year},
            "occurredOn.month": bson.M{"$gte": date.Month},
            "occurredOn.day":   bson.M{"$gt": date.Day}}, // happens in the next day
    },
    }
}
ndh0cuux

ndh0cuux2#

我认为在mongo bson pacakge中没有实现对civil.date类型的序列化。(没有函数MarshalBinary)
也许,为了更好的解决方案,它必须被改为time.time包,因为它在任何序列化中都有实现,比如bson,json或xml,甚至在google数据库中。
但如果civil.Date类型是所需的类型,则需要从年、月、日开始逐个查询比较字段,并且要考虑更新或修改集合的索引。

相关问题