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
,这样您就可以过滤文档,然后进行必要的操作。
我在我的项目中使用 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
,这样您就可以过滤文档,然后进行必要的操作。