【问题标题】:MongoDB can not find documents that has two different fields which are including equal dateMongoDB 找不到包含相同日期的两个不同字段的文档
【发布时间】:2019-08-03 21:58:19
【问题描述】:

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

我的表格/集合中最重要的字段是“开始日期”和“结束日期”,因为有了这些日期,我的数据库中的任何帖子都可以在网站上发布或从网站上删除。

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

当我将帖子插入数据库时​​,我有两个选择:

1) 永远不会从网站上删除此帖子。在这种情况下,我使“StartDate”和“EndDate”完全相同(相等)。这意味着该帖子永远不会从网站上删除,并且可以在“开始日期”发布。

2) 这篇文章可以/将会从网站上删除。当然,在这种情况下,“StartDate”和“EndDate”是不同的,根据这些日期(在这些日期之间),可以在网站上发布帖子。

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

在我的 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
}

【问题讨论】:

  • 请添加示例数据并描述“但在 MongoDB 中,我无法从我的帖子集合中获取结果”的意思。是空的吗?是错误的数据吗?它会发出错误吗?
  • 感谢您提及结果。经过第二次检查,我发现只有第二个 AND 运算符正在工作并返回结果。第一个 AND 不起作用。这意味着具有相同“开始日期”和“结束日期”的帖子不会返回。
  • 您只想返回那些具有相同 StartDateEndDate 的数据。这是你的问题吗?
  • 不,我想要两种类型的帖子,因为这个原因我的 OR 中有两个 AND:1)“StartDate”和“EndDate”是相等的,并且比 now() 更喜欢。 2)“StartDate”和“EndDate”不同,“StartDate”比now()小,“EndDate”比现在大。

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


【解决方案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 它会默认存在,你必须提到 "_id":0 如果你不想要那个字段。

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

【讨论】:

  • 非常聪明。我看到您首先缩短了我原来的 sql 查询并将“startdate enddate”,因为我们已经在 OR 的第一部分检查了它们的相等性,这意味着如果它不匹配,则它不相等,我们不需要再次检查。最后你只检查“enddate > now()”。是的,您的代码有效,我很感激,非常感谢。我认为$expr让你的代码变魔术。
猜你喜欢
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2013-03-06
  • 2023-03-15
  • 1970-01-01
相关资源
最近更新 更多