Запрос Mongo $ существует не возвращает правильные документы - PullRequest
2 голосов
/ 25 февраля 2012

Честно говоря, я не понимаю, как это вообще возможно:

> 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
        }
]

1 Ответ

4 голосов
/ 25 февраля 2012

Это потому, что вы используете разреженный индекс для 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 } }) result.

Существует билет JIRA, который объясняет это немного больше, и его можно отследить, если MongoDB получит сообщение об ошибке / предупреждение для этого: https://jira.mongodb.org/browse/SERVER-3918

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...