我在项目中使用的是Postgresql,但是最近我遇到了一些性能问题,因此决定尝试MongoDB。但是这一次我陷入了另一个问题海,我正在沉没。
我的表/集合中最重要的字段是“ StartDate”和“ EndDate”,因为有了这些日期,我数据库中的所有帖子都可以在网站上发布或从网站上删除。
这是我的问题,希望有人可以帮助我:
当我向数据库中插入帖子时,我有两种选择:
1)此帖子永远不会从网站上删除。在这种情况下,我要使“ StartDate”和“ EndDate”完全相同(相等)。这意味着该帖子永远不会从网站上删除,并且可以在“ StartDate”上发布。
2)此帖子可以/将从网站上删除。当然,在这种情况下,“ StartDate”和“ EndDate”是不同的,并且基于这些日期(在这些日期之间),可以在网站上发布帖子。
为什么这对我很重要,因为删除的帖子的标签也需要从标签页面中删除,删除的帖子的网址也需要从站点地图中删除等等...
在我的postgresql表中,这不是问题,而且非常简单:
SELECT * FROM posts WHERE
SATUS=true AND (
(enddate = startdate AND startdate <= Now())
OR
(enddate <> startdate AND startdate <= Now() AND enddate > Now())
)
但是在MongoDB中,即使我使用等效语法,也无法从我的帖子集中获得正确的结果?
我在StackOverflow中搜索了几天,这是我得到的最完美的聚合语法。 (用于MongoShell)
以下查询仅返回具有不同“ StartDate”和“ EndDate”以及当前正在发布帖子的字段。
OR的第一个AND部分似乎无效。仅返回第二个AND的结果。
var tmpDate = new Date();
db.getCollection('Posts').aggregate([
{ $project : {"_id":1,"Status":1,"EndDate":1,"StartDate":1}},
{ $match :
{ "$and": [
{ "Status": true },
{ "$or": [
{ "$and": [{ "EndDate": { "$eq": "StartDate" } }, { "StartDate": { "$lte": tmpDate } } ] },
{ "$and": [ { "EndDate": { "$ne": "StartDate" } }, { "StartDate": { "$lte": tmpDate } }, { "EndDate": { "$gt": tmpDate } } ] }
]
}
]
}
}
])
最后,我在StackOverflow上遇到了有关这种情况的答案,即MongoDB无法找到相等的日期或无法像其他数据库一样比较它们?
如何完成此过滤?还是我应该留在Postgresql。
PS:我正在从C#控制台应用程序插入测试文档,并以ISO日期插入日期:
DateTime tmpNow = DateTime.UtcNow;
tmpNow = Convert.ToDateTime(tmpNow.ToString("yyyy-MM-ddTHH:mm:00")).ToUniversalTime();
我正在按要求添加示例文档:
{
"_id" : NumberLong(1),
"Status" : true,
"Cat" : [
4
],
"Type" : 1,
"Title" : {
"Normal" : "Class aptent taciti sociosqu ad litora torquent per conubia",
"Spot" : null,
"Small" : null,
"Seo" : null
},
"Summary" : "Nam finibus nulla quis.",
"Article" : "<p>Maecenas malesuada augue nec</p>",
"Picture" : {
"Path" : "/Content/Images/detay9.jpg",
"Anchor" : "top",
"Rank" : 0,
"Desc" : null,
"Width" : 843,
"Height" : 1022
},
"Vertical" : null,
"Source" : "StackOverflow",
"Editor" : "An Editor",
"Related" : null,
"Tags" : [
"Causae",
"Nusquam",
"Percipitur",
"Rihanna",
"Saglik"
],
"StartDate" : ISODate("2019-05-05T13:44:00.000Z"),
"EndDate" : ISODate("2019-05-05T13:44:00.000Z"),
"UpdateDate" : ISODate("2019-05-05T13:44:00.000Z"),
"Rank" : 100,
"ReadCount" : 1064,
"Gallery" : null,
"List" : null,
"Shared" : false,
"Video" : null
}
答案 0 :(得分:1)
请尝试一下,希望它对您有用:
db.getCollection('Posts').aggregate([
{
$match:
{
"Status": true, "StartDate": { "$lte": tmpDate },
$expr: { $or: [{ $eq: ['$StartDate', '$EndDate'] }, { $gt: ['$EndDate', tmpDate] }] }
}
},
{ $project: {"Status": 1, "EndDate": 1, "StartDate": 1 } }
])
注意:
1)如果需要 _id ,则最终结果中,$project
不需要"_id":1
,默认情况下它会存在,您必须提及{ {1}}(如果您不想要该字段)。
2)回到您的陈述: "_id":0
,根据我的经验,我想说如果两个字段的类型相同,我们就可以做,否则您需要将一个字段转换为另一个字段表单,如果您正在使用Finally, I came across to answer about this situation at StackOverflow that MongoDB can not find equal dates or compare them like other DBs?
比较mongoDB文档中的两个字段,也可以解决问题。最好尽早使用$expr
那样的方式,这样您将过滤文档然后进行必要的操作。