2014-09-04 2 views
0

У меня есть коллекция с 20 пользователями, 19 из которых не имеют собственности created_at У нее есть разреженный индекс.
Когда я запускаю следующее в командной Монго линии он возвращает 1 документ (один с created_at собственности)Получить документы, которые не имеют собственности, где я сортирую по

db.users.find().sort({created_at: 1}) 

Как я могу сортировать по created_at, но и извлечь все объекты без created_at собственности

ПРИМЕЧАНИЕ: Это просто пример, когда реальная коллекция больше (а не пользователей), и нам нужен разреженный индекс в поле

ОБНОВЛЕНИЕ: я использую версию 2.4.9 (поэтому мне нужно ее обновить и использовать ниже) http://docs.mongodb.org/manual/core/index-sparse/#sparse-index-incomplete-results

ответ

2

Похоже, у вас есть "sparse index", определенный на поле «created_at», которая является единственной причиной, вы видите это поведение.

Возьмите следующие документы в качестве образца:

{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 } 
{ "_id" : ObjectId("5408222fb70a1512aacb5e7f"), "x" : 2 } 
{ "_id" : ObjectId("54082231b70a1512aacb5e80"), "x" : 3 } 

Если вы просто хотели «своего рода» на «у» здесь вы должны получить результат, как этот:

> db.test.find().sort({ y: 1 }) 
{ "_id" : ObjectId("5408222fb70a1512aacb5e7f"), "x" : 2 } 
{ "_id" : ObjectId("54082231b70a1512aacb5e80"), "x" : 3 } 
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 } 

Но если вы добавить разреженный индекс:

db.test.ensureIndex({ y: 1 },{ sparse: true }) 

Тогда результаты разные, но на небольших данных, нам нужно, чтобы заставить индекс:

> db.test.find().hint({ y: 1 }).sort({ y: 1 }) 
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 } 

Это единственный случай, когда это происходит, то по умолчанию является то, что не присутствует поле будет считаться null и «меньше» других ценностей, которые присутствуют.

Так, если индекс изменяется:

db.test.dropIndexes() 
db.test.ensureIndex({ y: 1 }) 

И вопрос тот же Постулаты, результаты будут такими же, как оригинал:

> db.test.find().hint({ y: 1 }).sort({ y: 1 }) 
{ "_id" : ObjectId("5408222fb70a1512aacb5e7f"), "x" : 2 } 
{ "_id" : ObjectId("54082231b70a1512aacb5e80"), "x" : 3 } 
{ "_id" : ObjectId("54082229b70a1512aacb5e7e"), "x" : 1, "y" : 1 } 

Так что, как разреженные индексы влияют на результаты здесь, исключая документы, где индексированное поле отсутствует.

Вы можете проверить следующим:

> db.test.getIndexes() 
    { 
      "v" : 1, 
      "key" : { 
        "y" : 1 
      }, 
      "name" : "y_1", 
      "ns" : "test.test", 
      "sparse" : true 
    } 

Если это время автоматически создается вашими настройками ODM, то вам может понадобиться, чтобы посмотреть на «вручную» с указанием условий индекса для использования.

Примечание: При фиксированном индексировании документы без поля «created_at» по-прежнему будут сверху с возрастающим порядком. Не изменяя данные, вам нужно что-то вроде структуры агрегации для прогнозирования значения, которое будет больше ожидаемых значений даты, когда этого уже не было.

+0

Мой вопрос действительно не представляет собой реальную коллекцию, но вы правы относительно разреженного индекса, и для этого требуется иметь разреженный индекс в этом поле. –

+0

@SanderVisser Да, но это редкий индекс, который производит этот результат. Пока разреженный индекс является «выбранным» индексом, тогда нет никакого способа ** изменить поведение, которое у вас есть сейчас. Вот почему я написал этот ответ, чтобы вы могли это понять. –

+0

Это возможно из версии 2.6 (из документов, под поведением) http://docs.mongodb.org/manual/core/index-sparse/ у нас есть версия 2.4.9, поэтому я рассматриваю обновление –

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