我正在使用django和mongo,我有这种类型的模型:
class ProductDate(EmbeddedDocument):
created = DateTimeField()
updated = DateTimeField(null=True)
class Product(Document):
product_id = IntField()
saves = IntField(default=0)
title = StringField(max_length=1000)
gender = StringField(choices=settings.GENDER_CHOICES, default=settings.UNISEX, max_length=50)
date = EmbeddedDocumentField(ProductDate)
现在用这个来做这样的查询:
queryset = queryset.filter(title=search)
我想先在创建的DateTime字段中按日期排序,然后按保存顺序排序。这样,具有相同日期而非时间的产品按保存数量排序。但是,我似乎无法找到将硅藻土转换为日期的方法,因此它只比较日期。
我无法做到:
.order_by("-date__created","-saves")
因为订单基于时间。
我尝试在mongo中使用aggregate,使用本教程:
但这对我没有帮助。
有人可以指导我如何做到这一点吗? 谢谢!
答案 0 :(得分:3)
您需要使用_get_collection()
访问者从pymongo集合中获取基础.aggregate()
方法,然后使用$project
创建截断日期信息。
您可以使用date aggregation operators:
Product._get_collection.aggregate([
{ "$project": {
"product_id": 1,
"saves": 1,
"title": 1,
"gender": 1,
"date": 1,
"partDate": {
"year": { "$year": "$date.created" },
"dayOfYear": { "$dayOfYear": "$date.created" }
}
}},
{ "$sort": {
"partDate.year": -1,
"partDate.dayOfYear": -1,
"saves": -1
}}
])
或者使用日期数学代替:
Product._get_collection.aggregate([
{ "$project": {
"product_id": 1,
"saves": 1,
"title": 1,
"gender": 1,
"date": 1,
"truncDate": {
"$subtract": [
{ "$subtract": [
"$date.created",
datetime.datetime.utcfromtimestamp(0)
] },
{ "$mod": [
{ "$subtract": [
"$date.created",
datetime.datetime.utcfromtimestamp(0)
] },
1000 * 60 * 60 * 24
]}
]
}
}},
{ "$sort": { "truncDate": -1, "saves": -1 }}
])
后者适用于对Date
BSON对象执行数学运算时,结果是从纪元开始的秒数的unix时间戳值。因此,减去纪元日期会产生一个时间戳值,然后四舍五入到一天。
- 编辑 -
更好的是,还有一点额外的数学,你会返回一个BSON Date
,它可以转换为API。只需应用$add
即可将数值转回BSON日期:
Product._get_collection.aggregate([
{ "$project": {
"product_id": 1,
"saves": 1,
"title": 1,
"gender": 1,
"date": 1,
"truncDate": {
"$add": [
{ "$subtract": [
{ "$subtract": [
"$date.created",
datetime.datetime.utcfromtimestamp(0)
]},
{ "$mod": [
{ "$subtract": [
"$date.created",
datetime.datetime.utcfromtimestamp(0)
]},
1000 * 60 * 60 * 24
]}
]},
datetime.datetime.utcfromtimestamp(0)
]
}
}},
{ "$sort": { "truncDate": -1, "saves": -1 }}
])
与转换的其余部分使用的基本纪元日期相同。
- 结束 -
然后你可以在适当的字段上$sort
。
当然这些是“原始”对象而不再是mongoengine文档,但聚合输出很少与集合输入完全相同。当然,在这种情况下,您可以选择相关字段并在需要时重新转换为文档类型。或者只是按原样处理结果。