我正在尝试使用如下插入的数据运行以下查询。无论出于何种原因,值为0的$ ne似乎都不起作用。我使用v2.0.4在linux和mac上试过这个。还使用mongo shell运行这些。
有人有什么想法吗?这是一个我误解的错误吗?
db.associated.insert({
"diskinfo" : {
"physical" : [
{"merror_count" : "Count: 0"},
{"merror_count" : "Count: 0"},
{"merror_count" : "Count: 0"},
{"merror_count" : "Count: 509"}
]
}})
db.associated.insert({
"diskinfo" : {
"physical" : [
{"merror_count" : "Count: 0"},
{"merror_count" : "Count: 5"},
{"merror_count" : "Count: 0"}
]
}})
db.associated.insert({
"diskinfo" : {
"physical" : [
{"merror_count" : "Count: 0"},
{"merror_count" : "Count: 0"},
{"merror_count" : "Count: 0"}
]
}})
在mongo shell上运行这些查询。并在评论中得到了结果
db.associated.find( { "diskinfo.physical.merror_count" : { $ne : 'Count: 0'}}).count() // Result: 0, Expected: 2 db.associated.find( { "diskinfo.physical.merror_count" : { $ne : 'Count: 509'}}).count() // Result: 2, Expected: 2 db.associated.find( { "diskinfo.physical.merror_count" : { $ne : 'Count: 5'}}).count() // Result: 2, Expected: 2
答案 0 :(得分:6)
虽然这是一个老问题,但我认为还有一些关于$ ne与数组语义的补充说明。
众所周知,mongo的行为具有
形式的查询db.collection.find({一个:V})
当a是一个数组时:它返回所有文档,使得(至少)数组键中的一个元素是v。在示例中:
db.associated.find({"diskinfo.physical.merror_count" : "Count: 0"}).count()
返回3,因为数组“diskinfo.physical.merror_count”在集合的三个文档中包含值“Count:0”。
然后,期待
似乎是合理的(至少是可能的)db.collection.find({一个:{$ NE:V}})
将返回文档,使得a包含与v不同的内容。 但是,这不是Mongo中的行为。相反,使用$ ne表示仅选择那些阵列a不包含v的文档。
这个语义在开始时看起来很奇怪但是如果我们以这种方式考虑表达式就有意义了:
db.collection.find({a:v}).count() + db.collection.find({a:{$ne:v}}).count()
返回集合中的元素总数。因此,在该示例中,
是有意义的db.associated.find({"diskinfo.physical.merror_count" : {$ne: "Count: 0"}}).count()
返回0,因为数组“diskinfo.physical.merror_count”在集合的3个文档中至少包含一次“Count:0”。
答案 1 :(得分:4)
这些结果是正确的。
您的期望可能基于嵌入式数组中与谓词匹配的元素数量。但是,它是满足查询要求的文档数量。
在第一种情况下,您查询所有没有diskinfo.physical.merror_count等于'Count:0'的文档。每个文件的diskinfo.physical.merror_count都是'Count:0',所以你回来0。
以这种方式查看,集合中的每个文档都有一个diskinfo.physical.merror_count值,该值不是'Count:0'。如果你以平等而不是不平等的形式提问,那么你可以回到这三个方面。
您是否尝试查找所有仅条目为'Count:0'的文档?
似乎没有直接的方法来做到这一点,但是一个可以解决这个问题的查询是:
db.associated.find( { "diskinfo.physical.merror_count" : { $gt : 'Count: 0'}}).count()
如果计数实际上是整数,至少这将是解决方案 - 它恰好也适用于字符串,因为“1”>“0”等等。
答案 2 :(得分:1)
另一种解决方案,使用$elemMatch
:
find( { "diskinfo.physical" : { $elemMatch: { merror_count: { $ne: 'Count: 0' } } )
此将匹配一个数组,其中只有一个项目为$ne
。另一个优点是你可以为匹配添加更多运算符,以执行复杂的操作:
find ({
'partners.id': 'C30016',
'partners': { $elemMatch: {
id: { $ne: 'C30016' },
type: 'shipper'
}
}
})
(查找托运人'C30016'帐户的所有合作伙伴。)