2013-12-22 2 views
2

Нужна помощь с запросом Mongo на основе значения атрибута subdocument, но также и подавления этого атрибута поддокумента, появляющегося в результатах.Проектирование поддокума MongoDB

Вот мои пользовательские объекты:

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : true 
    }, 
    { 
     "address" : "[email protected]", 
     "default" : false 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : false 
    }, 
    { 
     "address" : "[email protected]", 
     "default" : true 
    } 
    ] 
} 

Моя цель состоит в том, чтобы получить следующий результат (с «emails.default»: правда, но без «emails.default» атрибут появляется в результатах):

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    } 
    ] 
} 

Использование $ позиционную оператора:

collection.find({"emails.default":true}, {"username":1,"emails.$":1}) 

я получаю правильные поддокументы электронной почты в ар груша, но я все еще получаю «emails.default» атрибут обратно:

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : true 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
     "default" : true 
    } 
    ] 
} 

и по какой-то причине, когда я использую это заявление:

collection.find({"emails.default":true}, {"username":1,"emails.address":1}) 

я получаю следующий результат (как если бы запрос часть заявления была проигнорирована)

{ 
    "username" : "abc", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    }, 
    { 
     "address" : "[email protected]", 
    } 
    ] 
}, 
{ 
    "username" : "xyz", 
    "emails" : [ 
    { 
     "address" : "[email protected]", 
    }, 
    { 
     "address" : "[email protected]", 
    } 
    ] 
} 

Помогите оценить, спасибо заранее.

ответ

1

Я не думаю, что это поддерживаемая функция. Вы запрашиваете проецирование выбранных полей внутри документа массива. См. Это ticket

Но я думаю, что ваша структура документа будет хранить много избыточных данных. Будет только один адрес электронной почты по умолчанию. Сделайте это частью родительского документа. Обновления/прогнозы будут намного проще. Ваш массив emails теперь фактически хранит только.

3

С оператором позиционирования (как и в MongoDB 2.6) вы не можете выборочно исключать поля элемента массива, на который вы соответствуете.

Однако, вы можете использовать Aggregation Framework в MongoDB 2.2+ для достижения желаемого результата:

db.user.aggregate(

    // Match on relevant documents to optimize query 
    { $match: { 
     username: "abc" 
    }}, 

    // Convert the "emails" address into a stream of documents 
    { $unwind: "$emails" }, 

    // Only include the emails with default:true 
    { $match: { 
     "emails.default" : true 
    }}, 

    // Project the desired fields 
    { $project: { 
     _id : 0, 
     username: 1, 
     "emails.address": 1 
    }} 
) 

Пример результата:

{ 
    "username" : "abc", 
    "emails" : { 
     "address" : "[email protected]" 
    } 
} 
Смежные вопросы