mongodb中的时间序列数据如下:
{ "_id" : ObjectId("558912b845cea070a982d894"), "code" : "ZL0KOP", "time" : NumberLong("1420128024000"),"direction" : "10", "siteId" : "0000"}
{ "_id" : ObjectId("558912b845cea070a982d895"), "code" : "AQ0ZSQ", "time" : NumberLong("1420128025000"),"direction" : "10", "siteId" : "0000"}
{ "_id" : ObjectId("558912b845cea070a982d896"), "code" : "AQ0ZSQ", "time" : NumberLong("1420128003000"),"direction" : "10", "siteId" : "0000"}
{ "_id" : ObjectId("558912b845cea070a982d897"), "code" : "ZL0KOP", "time" : NumberLong("1420041724000"),"direction" : "10", "siteId" : "0000"}
{ "_id" : ObjectId("558912b845cea070a982d89e"), "code" : "YBUHCW", "time" : NumberLong("1420041732000"),"direction" : "10", "siteId" : "0002"}
{ "_id" : ObjectId("558912b845cea070a982d8a1"), "code" : "U48AIW", "time" : NumberLong("1420041729000"),"direction" : "10", "siteId" : "0002"}
{ "_id" : ObjectId("558912b845cea070a982d8a0"), "code" : "OJ3A06", "time" : NumberLong("1420300927000"),"direction" : "10", "siteId" : "0000"}
{ "_id" : ObjectId("558912b845cea070a982d89d"), "code" : "AQ0ZSQ", "time" : NumberLong("1420300885000"),"direction" : "10", "siteId" : "0003"}
{ "_id" : ObjectId("558912b845cea070a982d8a2"), "code" : "ZLV05H", "time" : NumberLong("1420300922000"),"direction" : "10", "siteId" : "0001"}
{ "_id" : ObjectId("558912b845cea070a982d8a3"), "code" : "AQ0ZSQ", "time" : NumberLong("1420300928000"),"direction" : "10", "siteId" : "0000"}
需要过滤掉符合两个或多个条件的代码。 例如:
condition1: 1420128000000 < time < 1420128030000,siteId == 0000
condition2: 1420300880000 < time < 1420300890000,siteId == 0003
唯一符合上述所有条件的代码应为:
{&#34;代码&#34; :&#34; AQ0ZSQ&#34;}
我使用以下查询:
db.codes.find({$and:[{'time': {'$gt': 1420128000000,'$lt': 1420128030000}, 'siteId': "0000"},{'time': {'$gt': 1420300880000,'$lt': 1420300890000}},{'siteId':'0003'}]})
未找到任何结果,解释显示:
"parsedQuery" : {
"$and" : [
{
"time" : {
"$lt" : 1421856012000
}
},
{
"time" : {
"$lt" : 1420560012000
}
},
{
"siteId" : {
"$eq" : "0000"
}
},
{
"siteId" : {
"$eq" : "0000"
}
},
{
"time" : {
"$gt" : 1421722392000
}
},
{
"time" : {
"$gt" : 1420426392000
}
}
]
},
这显然不正确。 那么我怎样才能找到正确的结果?
答案 0 :(得分:0)
你的意思是$or
而不是$and
。 &#34; AND&#34;是不可能的,因为没有记录同时具有&#34; 0000&#34;和&#34; 0003&#34;对于siteId。所以你的意思是&#34;要么&#34;这意味着&#34; OR&#34;:
db.codes.find({
"$or": [
{
"time": { "$gt": 1420128000000, "$lt": 1420128030000 },
"siteId": "0000"
},
{
"time": { "$gt": 1420300880000, "$lt": 1420300890000 },
"siteId": "0003"
}
]
})
使用您期望的密钥为您提供结果:
{
"_id" : ObjectId("558912b845cea070a982d895"),
"code" : "AQ0ZSQ",
"time" : NumberLong("1420128025000"),
"direction" : "10",
"siteId" : "0000"
},
{
"_id" : ObjectId("558912b845cea070a982d896"),
"code" : "AQ0ZSQ",
"time" : NumberLong("1420128003000"),
"direction" : "10",
"siteId" : "0000"
},
{
"_id" : ObjectId("558912b845cea070a982d89d"),
"code" : "AQ0ZSQ",
"time" : NumberLong("1420300885000"),
"direction" : "10",
"siteId" : "0003"
}
简而言之由于这里的条款似乎存在误解,我将尽可能简单地解释一下。让我们考虑一下这些基本文件:
{ "a": 1, "b": true },
{ "a": 2, "b": false },
{ "a": 3, "b": true },
{ "a": 4, "b": false },
{ "a": 5, "b": true },
{ "a": 6, "b": true }
现在,当第一次聚焦于单个范围匹配时,以下将产生结果:
db.collection.find({ "a": { "$gt": 1, "$lt": 6 } })
由于这里的六个文件中有四个将包含&#34; a&#34;落在指定范围之间。
现在你也可以使用&#34;两个&#34;此范围在$and
条件范围内,如下所示:
db.collection.find({
"$and": [
{ "a": { "$gt": 1, "$lt": 6 } },
{ "a": { "$gt": 2, "$lt": 5 } }
]
})
现在再次使用&#34; a&#34;对于3和4将匹配&#34;两者&#34;当然条件是丢弃2和5的值,因为没有满足第二个条件。
这里的还原点表达式实际上可以简化为只有&#34;更大&#34;的范围。最小值和&#34;较小的&#34;最大值:
db.collection.find({ "a": { "$gt": 2, "$lt": 5 } })
与上述结果相同。
而不是&#34;包含&#34;逻辑同样适用于&#34;十字路口&#34;条件,所以如下:
db.collection.find({
"$and": [
{ "a": { "$gt": 1, "$lt": 4 } },
{ "a": { "$gt": 2, "$lt": 6 } }
]
})
然后通过相同的&#34;最小值&#34;减少到这个基本陈述。和&#34;最大&#34;规则:
db.collection.find({ "a": { "$gt": 2, "$lt": 4 } })
两者都只返回基本缩减所涵盖的文档3。
但是,如果范围中无重叠,则无法匹配:
db.collection.find({
"$and": [
{ "a": { "$gt": 1, "$lt": 3 } },
{ "a": { "$gt": 2, "$lt": 6 } }
]
})
没有文件符合这些条件,因为3,4,5符合第二个声明,但所有3,4,5都被第一个声明排除在外。再次,这只是&#34;减少&#34;到此为止:
db.collection.find({ "a": { "$gt": 2, "$lt": 3 } })
此集合中2到3之间的数字明显不匹配。
现在看第二个&#34; b&#34;只有财产,你可以这样做:
db.collection.find({ "b": true })
仅按预期返回true
的结果。但如果你试过这个:
db.collection.find({
"$and": [
{ "b": true },
{ "b": false }
]
})
然后就是&#34;不匹配&#34;因为没有单个文档同时包含true
和 false
用于&#34; b&#34; 同时。只有$or
条件才能匹配文档测试&#34;或者#34;这些价值观:
db.collection.find({
"$or": [
{ "b": true },
{ "b": false }
]
})
当然,样本中的所有文档都没有包含&#34; b&#34;的其他可能值。在条件中没有提到。
较短的运算符是$in
运算符,可以测试&#34;或&#34;在没有完全声明它的同一领域,如:
db.collection.find({ "b": { "$in": [true,false] } })
现在,如果你&#34;结合&#34;原则,$and
的第二次尝试如何与范围组合不起作用应该是明确的:
db.collection.find({
"$and": [
{ "a": { "$gt": 1, "$lt": 4 }, "b": true },
{ "a": { "$gt": 2, "$lt": 6 }, "b": false }
]
})
所以虽然&#34;范围&#34;为&#34; a&#34;提供满意的文件等于3该文件没有&#34;两者&#34; true
和false
值。它只是&#34;只有&#34;值为true
,因此没有符合条件且没有文档匹配。
为了使文档与&#34; a&#34;匹配。 3然后逻辑将被写入&#34; redcued&#34;形式如此:
db.collection.find({
"a": { "$gt": 2, "$lt": 4 },
"b": { "$in": [true,false] }
})
在那种情况下,然后记录&#34; a&#34;等于3是匹配,因为找到了减少的范围以及&#34; b&#34; beign等于true/false
的其中一个值。
当然最后要考虑&#34; b&#34;作为&#34;或&#34;你会做的条件:
db.collection.find({
"$or": [
{ "a": { "$gt": 2, "$lt": 4 } },
{ "b": { "$in": [true,false] } }
]
})
当然匹配&#34;一切&#34;在样本中作为第一个&#34;范围&#34;匹配的文件&#34; a&#34;等于3但所有文件包含&#34; b&#34;的值这是true/false
。
这就是这一切的结果。如前所述,有一个基本的还原规则可以应用于一个范围,对于一个&#34;奇异的&#34;它只是不可能。值一次具有多个值。
这是基本逻辑,而不是理论物理,所以Schrödinger's cat不适用于此:)