MongoDB找不到包含两个不同字段(包括相等日期)的文档

时间:2019-08-03 21:58:19

标签: mongodb postgresql mongodb-query mongo-shell isodate

我在项目中使用的是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
}

1 个答案:

答案 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那样的方式,这样您将过滤文档然后进行必要的操作。