2014-10-06 2 views
-1

У меня есть следующий Монго документ, который является частью более крупного документа под названием атрибутов, который также имеет цвет и размерКак получить MongoDB глубоко Embeded идентификатор документа

> db.attributes.find({'name': {'en-UK': 'Fabric'}}).pretty() 
{ 
    "_id" : ObjectId("543261cda14c971132fa2b91"), 
    "values" : [ 
     { 
      "source" : [ 
       { 
        "_id" : ObjectId("543261cda14c971132fa2b79"), 
        "name" : { 
         "en-UK" : "Combed Cotton" 
        } 
       }, 
      ], 
      "name" : [ 
       { 
        "_id" : ObjectId("543261cda14c971132fa2b85"), 
        "name" : { 
         "en-UK" : "Brushed 3-ply" 
        } 
       }, 
       { 
        "_id" : ObjectId("543261cda14c971132fa2b8f"), 
        "name" : { 
         "en-UK" : "Plain Weave" 
        } 
       }, 
       { 
        "_id" : ObjectId("543261cda14c971132fa2b90"), 
        "name" : { 
         "en-UK" : "1x1 Rib" 
        } 
       } 
      ] 
     } 
    ], 
    "name" : { 
     "en-UK" : "Fabric" 
    } 

}

Я пытаюсь верните _id для дополнительного документа и укажите следующее:

db.attributes.aggregate([ 
    { '$match': {'name.en-UK': 'Fabric'} }, 
    { '$unwind' : '$values' }, 
    { '$project': { 'name' : '$values.name'} }, 
    { '$match': { '$and': [{"name.name.en-UK" : "1x1 Rib"} ] }} 
]) 

Каков правильный способ сделать это?

Кроме того, значения Fabric представляет собой массив из двух элементов, source и name, но если я заполнить это нравится:

> db.attributes.find({'name': {'en-UK': 'Fabric'}}).pretty() 
{ 
    "_id" : ObjectId("543261cda14c971132fa2b91"), 
    "values" : { 
      "source" : [{ ... }] 
      "name": [{ ... }] 
    } 
} 

Я получаю следующую ошибку

"ERRMSG": «исключение : $ unwind: значение в конце пути поля должно быть массивом «

Но если я заверну его в квадратные скобки, то это работает, так что

> db.attributes.find({'name': {'en-UK': 'Fabric'}}).pretty() 
{ 
    "_id" : ObjectId("543261cda14c971132fa2b91"), 
    "values" : [{ 
      "source" : [{ ... }], 
      "name": [{ ... }] 
    }] 
} 

, что у меня отсутствует, как values массив из двух объектов, source и name каждый из которых содержит список массивов

Любой совет высоко ценится

ответ

0

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

К счастью, есть несколько способов обойти это. А именно, либо «тестирование» на наличие массива при отправке исходного запроса. Или фактически «подставляя» отсутствующий элемент для какого-то массива при обработке конвейера.

Вот оба подхода в том, что фактически является излишним, так как форма первого $match состояние действительно сортирует это:

db.attributes.aggregate([ 
    { "$match": { 
     "name.en-UK": "Fabric", 
     "values.0": { "$exists": true } 
    }}, 
    { "$project": { 
     "name": 1, 
     "values": { "$ifNull": [ "$values", [] ] } 
    }}, 
    { "$unwind": "$values" }, 
    { "$unwind": "$values.name" }, 
    { "$match": { "values.name.name.en-UK" : "1x1 Rib" }} 
]) 

Так как я уже сказал. Действительно избыточно в том, что начальный $match фактически спрашивает, существует ли фактически «начальный элемент массива». Какое средство означает, что там есть массив.

Вторая фаза $project фактически использует оператор $ifNull для «заполнения» значения (или в основном пустого массива), где тестируемый элемент не существует. Мы все еще тестировали, но это демонстрирует различные подходы.

Но основная идея - либо «избегать», либо «заполнять», когда ваш документ не имеет ожидаемых данных, которые вы хотите обработать. Какая причина вашей ошибки.

+0

Извините, я получаю пустой результат, '{" result ": []," ok ": 1}' – khinester

+0

@khinester. Вы не совсем поняли. В следующий раз удалите символы «tab» из вашего сообщения, когда вы отправляете. Отредактировано с помощью важных строк. –

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