MongoDB 找不到包含两个不同字段且日期相同的文档

MongoDB can not find documents that has two different fields which are including equal date

我在我的项目中使用 Postgresql,但最近我遇到了一些性能问题并决定尝试 MongoDB。但是这次我在另一个问题的海洋中,我正在下沉。

我的 Table/Collection 最重要的字段是 "StartDate" 和 "EndDate" 因为有了这些日期,我数据库中的任何 post(s) 都可以在网站上发布或从站点中删除。

这是我的问题,希望有人能帮助我:

当我向数据库中插入 post 时,我有两个选择:

1) 此 post 永远不会从站点中删除。在这种情况下,我使 "StartDate" 和 "EndDate" 完全相同(相等)。这意味着此 post 永远不会从网站上删除,并且可以在 "StartDate".

上发布

2) post 可以从站点中删除 be/will。当然,在这种情况下 "StartDate" 和 "EndDate" 是不同的,并且根据这些日期(在这些日期之间)可以在网站上发布 post。

为什么这对我很重要,因为已删除的 posts 的标签也需要从标签页面中删除,已删除的 posts 的 url 也需要从站点地图中删除等...

在我的 postgresql 表中,这不是问题,而且查询非常简单:

SELECT * FROM posts WHERE 
      SATUS=true AND (
        (enddate = startdate AND startdate <= Now()) 
        OR 
        (enddate <> startdate AND startdate <= Now() AND enddate > Now())
      )

但是在 MongoDB 中,即使我使用等效语法,我也无法从我的 post 集合中获得正确的结果?

我在 Whosebug 中搜索了好几天,这是我得到的最完美的聚合语法。 (对于 MongoShell)

下面的查询 returns 仅查询具有不同 "StartDate" 和 "EndDate" 且当前发布 posts.

的字段

OR 的第一个 AND 部分似乎不起作用。只有 returns 第二个 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 } } ] } 
            ] 
        } 
        ] 
    }
}
])

最后,我在 Whosebug 回答了这种情况,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" : "Whosebug",
    "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
}

请试试这个,我希望它对你有用:

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 它会默认存在,你如果您不想要该字段,请提及 "_id":0

2) 回到你的陈述:Finally, I came across to answer about this situation at Whosebug that MongoDB can not find equal dates or compare them like other DBs?,根据我的经验,如果两个字段的类型相同,我会说我们可以做,否则你需要将一个转换为另一种形式,如果您比较 mongoDB 文档中的两个字段,使用 $expr 也可以。最好尽早使用 $match,这样您就可以过滤文档,然后进行必要的操作。