2014-12-05 5 views
2

У меня есть коллекция в MongoDB, где поля вложенной под корень языка:Выберите вложенные поля в Монго дб

{ 
    en: { 
     title: "eng title", 
     content: "eng content", 
    }, 
    it: { 
     title: "it title", 
     content: "it content" 
    } 
    //common attributes for all languages 
    images: { 
     mainImage: "dataURL", 
     thumbImage: "dataURL" 
    } 
} 

У меня есть переменная с именем «currentLang»; Мне нужно найти документ по названию, выбрав только объект currentLang и общие поля (изображения в этом примере); , но для объекта currentLang я хотел бы, чтобы выходной документ не был вложен; например, имея currentLang = "EN"

желаемый результат:

{ 
    title: "eng title", 
    content: "eng content", 
    images: { 
     mainImage: "dataURL", 
     thumbImage: "dataURL" 
    } 
} 

Возможно ли это?

ответ

2

Вам необходимо агрегировать, как показано ниже:

  • Построить find объект, чтобы соответствовать только записи, содержащие ($exists) язык.
  • Построить объект Projection, чтобы проектировать поля.

Код:

var currentLang = "en"; 
var project = {}; 
project["title"] = "$"+currentLang+".title"; 
project["content"] = "$"+currentLang+".content"; 
project["images"] = 1; 

var find = {}; 
find[currentLang] = {"$exists":true}; 

db.collection.aggregate([ 
{$match:find}, 
{$project:project} 
]) 
+0

Этом это именно тот код, который я использую сейчас; но выходной документ все еще вложен в «en»; Я хотел бы иметь все поля в корневом элементе, например, желаемый вывод, написанный выше –

+0

@CerealKiller. Затем вам нужно заполнить, спроецировать поле с псевдонимом. См. Обновленный ответ. – BatScream

+0

Хорошо, это правильно; к сожалению, я использую mongo внутри Meteor.js, где агрегация, похоже, не поддерживается; извините, когда я написал вопрос, я не знал, что ... –

1

Я не знаю, как вы запрашивая, поэтому я предполагаю, что вы собираетесь непосредственно через клиент Монго. Предполагая, что вы определили переменную

>currentLang = "en"; 

Вы можете запустить aggregation operation и используя $project operator, перестраивать представление документа.

Вот пример, который я тестировал:

> db.test.aggregate({$project: 
     {_id: 0, 
     title: "$" + currentLang + ".title", 
     content: "$" + currentLang + ".content", 
     images: 1 
     } 
    }).pretty(); 
{ 
    "images" : { 
     "mainImage" : "dataURL", 
     "thumbImage" : "dataURL" 
    }, 
    "title" : "eng title", 
    "content" : "eng content" 
} 

Если вы хотите совместить это с реальным запросом, вы можете просто включить его в качестве $match operator, что-то вроде:

> db.test.aggregate(
    {$match: 
     {"en.title": "eng title"} 
    }, 
    {$project: 
     {_id: 0, 
     title: "$" + currentLang + ".title", 
     content: "$" + currentLang + ".content", 
     images: 1 
     } 
    }).pretty(); 
Смежные вопросы