4

我正在尝试使用插入的数据运行以下查询,如下所示。无论出于何种原因,价值为 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()
// 结果:0,预期:2
db.associated.find( { "diskinfo.physical.merror_count" : { $ne : 'Count: 509'}}).count()
// 结果:2,预期:2
db.associated.find( { "diskinfo.physical.merror_count" : { $ne : 'Count: 5'}}).count()
// 结果:2,预期:2
4

3 回答 3

8

虽然这是一个老问题,但我认为仍然有一些关于 $ne 与数组的语义的额外解释。

  1. 众所周知,mongo 的行为具有以下形式的查询

    db.collection.find({a:v})

当 a 是一个数组时:它返回所有文档,使得(至少)数组键中的一个元素是 v。在示例中:

db.associated.find({"diskinfo.physical.merror_count" : "Count: 0"}).count()

返回 3,因为数组“diskinfo.physical.merror_count”在集合的三个文档中包含一个值“Count: 0”。

  1. 那么,期望

    db.collection.find({a:{$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”。

于 2016-04-07T18:18:05.120 回答
4

这些结果是正确的。

您的期望可能基于嵌入数组中与您的谓词匹配的元素数量。但是,您将获得满足查询的文档数量。

在第一种情况下,您查询所有 diskinfo.physical.merror_count 不等于“计数:0”的文档。每个文档都有 diskinfo.physical.merror_count 'Count: 0' 所以你会得到 0。

这样看,您的集合中的每个文档都有一个 diskinfo.physical.merror_count 值,它不是“计数:0”。如果你用平等而不是不平等进行查询,你会得到所有三个。

您是否要查找所有只有“计数:0”条目的文档?

似乎没有一种直接的方法可以做到这一点,但是一个可以让你做到这一点的查询是:

db.associated.find( { "diskinfo.physical.merror_count" : { $gt : 'Count: 0'}}).count()

如果计数实际上是整数,至少这将是解决方案 - 它恰好也适用于字符串,因为“1”>“0”等。

于 2012-06-06T05:18:52.380 回答
1

另一种解决方案,使用$elemMatch

find( { "diskinfo.physical" : { $elemMatch: { merror_count: { $ne: 'Count: 0' } } )

匹配一个数组,其中只有一项是$ne. 另一个优点是您可以在匹配中添加更多运算符,以执行复杂的操作,例如:

find ({
  'partners.id': 'C30016',
  'partners': { $elemMatch: {
     id: { $ne: 'C30016' },
     type: 'shipper'
   }
  } 
})

(查找帐户“C30016”中所有作为托运人的合作伙伴)。

于 2016-01-06T11:39:25.180 回答