2012-02-25 50 views
2

老实说,我不明白这是怎么能办到:

> db.ts.find({"bcoded_metadata" : { "$exists" : true} }).count() 
199049 
> db.ts.find({"bcoded_metadata" : { "$exists" : false} }).count() 
0 
> db.ts.count() 
2507873 

我认为第一和第二查询的总和必须等于第三。

我需要从集合中选择“bcoded_metadata”不存在,但查询不返回任何内容的所有元素。 当我在简单的python脚本中迭代这个集合并手动检查“bcoded_metadata”是否存在时,一切都按预期工作。

from pymongo import Connection 
connection = Connection('127.0.0.1', 27017) 
db = connection.data 
c = 0 
for item in db.ts.find(): 
    if not "bcoded_metadata" in item.keys(): 
      c+= 1 
print c 



python test.py 
2308824 

这是正确的答案。

问题的根源在哪里?

指标:

> db.ts.getIndexes(); 
[ 
     { 
       "name" : "_id_", 
       "ns" : "data.ts", 
       "key" : { 
         "_id" : 1 
       }, 
       "v" : 0 
     }, 
     { 
       "_id" : ObjectId("4f3c299b4c4a5ccfddbe4069"), 
       "ns" : "data.ts", 
       "key" : { 
         "last_seen" : 1 
       }, 
       "name" : "last_seen_1", 
       "v" : 0 
     }, 
     { 
       "_id" : ObjectId("4f3c2cef4c4a5ccfddbe406a"), 
       "ns" : "data.ts", 
       "key" : { 
         "attempts" : -1 
       }, 
       "name" : "attempts_-1", 
       "v" : 0 
     }, 
     { 
       "_id" : ObjectId("4f4279ed6aca13be31acbe6d"), 
       "ns" : "data.ts", 
       "key" : { 
         "bcoded_metadata" : 1 
       }, 
       "name" : "bcoded_metadata_1", 
       "sparse" : true, 
       "v" : 0 
     } 
] 
+0

是从蒙戈外壳或驱动程序查询? – 2012-02-25 10:52:28

+0

@marcolinux查询是从shell执行的。显然,python脚本通过驱动程序工作。 – Moonwalker 2012-02-25 10:58:49

+0

也许这个错误? https://jira.mongodb.org/browse/SERVER-3918 – 2012-02-25 11:07:39

回答

4

这是因为你用一个稀疏索引bcoded_metadata。如果您在bcoded_metadata上有一个稀疏索引,那么索引将不包含没有字段bcoded_metadata的文档。没有bcoded_metadata字段的文档不是您原始查询的一部分,因此“count”将返回0.

如果您只运行find:db.ts.find({"bcoded_metadata" : { "$exists" : false } }),那么您也不会得到任何结果。您可以使用非稀疏索引,也可以使用db.ts.count();进行完整计数,并减去db.ts.find({"bcoded_metadata" : { "$exists" : true } })结果的结果。

有一个JIRA票,解释多一点,并且情况下可以跟踪MongoDB中获得了这样的错误/警告消息:https://jira.mongodb.org/browse/SERVER-3918

+0

其实我需要遍历文件没有“bcoded_metadata”。 我该怎么办?有什么办法可以强制密集索引?由于ensureIndex({“bcoded_metadata”:1},{sparce:false}); 没有按预期工作,我仍然有稀疏的指数。 – Moonwalker 2012-02-25 14:50:32

+0

好的,我刚刚删除了“bcoded_metadata”的索引,并解决了问题。谢谢。 – Moonwalker 2012-02-26 07:45:44

+0

而不是删除该索引,请考虑使它*不*稀疏索引。默认情况下索引不是稀疏的,所以这是你自己完成的。 – Derick 2012-02-26 16:23:16