Naz*_*riy 5 django datetime mongodb mongoengine django-rest-framework
我将 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)
Run Code Online (Sandbox Code Playgroud)
现在,当我进行这样的查询时:
queryset = queryset.filter(title=search)
Run Code Online (Sandbox Code Playgroud)
我想首先按创建的日期时间字段中的日期排序,然后按保存排序。这样,具有相同日期而不是时间的产品将按保存次数排序。但是,我似乎找不到将硅藻土转换为日期的方法,以便它仅比较日期。
我不能这样做:
.order_by("-date__created","-saves")
Run Code Online (Sandbox Code Playgroud)
因为这是根据时间排序的。
我尝试在 mongo 中使用聚合,通过本教程:
但这对我没有帮助。
有人可以指导我如何做到这一点吗?谢谢你!
您需要使用_get_collection()
访问器从 pymongo 集合中获取底层.aggregate()
方法,然后使用$project
来创建截断的日期信息。
您可以使用日期聚合运算符符:
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
}}
])
Run Code Online (Sandbox Code Playgroud)
或者用日期数学代替:
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 }}
])
Run Code Online (Sandbox Code Playgroud)
后者的工作原理是,当您对Date
BSON 对象进行数学运算时,结果是从纪元开始的秒数的 unix 时间戳值。因此,减去纪元日期会产生一个时间戳值,然后四舍五入为单日。
- 编辑 -
更好的是,进行一些额外的数学计算,您就可以返回一个 BSON Date
,该 BSON 可以转换回 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 }}
])
Run Code Online (Sandbox Code Playgroud)
这与其余转换中使用的基本纪元日期应用程序相同。
- 结尾 -
然后你可以$sort
在适当的字段上。
当然,这些是“原始”对象,不再是 mongoengine 文档,但是聚合输出很少与集合输入完全相同。当然,在这种情况下,您可以根据需要选择相关字段并重新转换为您的文档类型。或者按原样使用结果。
归档时间: |
|
查看次数: |
2897 次 |
最近记录: |