2012-02-25 2 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

это ваш запрос от Монго оболочки или с водителем? –

+0

Запрос @marcolinux выполняется из командной строки. Очевидно, скрипт python работает через драйвер. – Moonwalker

+0

Может, эта ошибка? https://jira.mongodb.org/browse/SERVER-3918 –

ответ

4

Это потому, что вы используете разреженный индекс для bcoded_metadata. Если у вас есть разреженный индекс в bcoded_metadata, то индекс не будет содержать документы, у которых нет поля bcoded_metadata. Документы без поля bcoded_metadata не являются частью вашего первоначального запроса, и, следовательно, «count» вернет 0.

Если вы запустите только найти: 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». Что мне делать? Есть ли способ обеспечить плотный индекс? Потому что makeIndex ({"bcoded_metadata": 1}, {sparce: false}); не работает должным образом, после этого у меня все еще есть разреженный индекс. – Moonwalker

+0

Хорошо, я только что сбросил индексы для «bcoded_metadata» и решил проблему. Спасибо. – Moonwalker

+0

Вместо того, чтобы отбрасывать этот индекс, подумайте о том, чтобы сделать его * не * редким индексом. Индексы по умолчанию не являются скудными, так что это то, что вы сделали сами. – Derick

Смежные вопросы