2015-05-15 2 views
0

У меня есть JSON-файл, который был импортирован в Монго:элементов поддокумента проекта, когда имя элемента не известны в Монго

{ 
    "people": { 
     "Employee1234": { 
      "salary": 10000, 
      "dept": "accounting" 
     }, 
     "Employee1235": { 
      "salary": 40000, 
      "dept": "CEO" 
     }, 
     ... 
    } 
} 

Я хочу, чтобы быть в состоянии найти все уникальные зарплаты и ведомств народа.

Это сложно, потому что people не находятся в [] с их идентификатором в качестве поля, а элементами являются их EID. Я пытаюсь сделать эквивалент find({},{people.*.dept}), но вы не можете использовать шаблон *. Как я могу запросить это (Учитывая, что это схема существующих документов)?

ответ

1

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

{ 
    "people": [ 
     { 
      "name": "Employee1234", 
      "salary": 10000, 
      "dept": "accounting" 
     }, 
      "name": "Employee1235", 
      "salary": 40000, 
      "dept": "CEO" 
     }  
    ] 
} 

Преобразования текущей схемы к одному выше будет использовать некоторую родную JavaScript:

db.collection.find().forEach(function(doc){ 
    var people = [], 
     keys = Object.keys(doc.people); 
     obj = {}; 

    keys.forEach(function(key){ 
     obj = doc.people[key]; 
     obj.name = key 
     people.push(obj); 
    }); 

    doc.people = people; 
    db.collection.save(doc); 
}); 

После изменения схемы, вы бы теперь в состоянии запрос с использованием aggregation framework. Агрегация трубопровод, который найдет все уникальные зарплаты и ведомств людей следующим образом:

db.collection.aggregate([ 
    { 
     "$unwind": "$people" 
    }, 
    { 
     "$group": { 
      "_id": { 
       "salary": "$people.salary", 
       "department": "$people.dept" 
      }, 
      "count": { 
       "$sum": 1 
      } 
     } 
    }, 
    { 
     "$match": { "count": 1 } 
    } 
]); 

Для приведенного выше документа образца, результат будет:

/* 0 */ 
{ 
    "result" : [ 
     { 
      "_id" : { 
       "salary" : 40000, 
       "department" : "CEO" 
      }, 
      "count" : 1 
     }, 
     { 
      "_id" : { 
       "salary" : 10000, 
       "department" : "accounting" 
      }, 
      "count" : 1 
     } 
    ], 
    "ok" : 1 
} 
+0

тьфу. Я боялся, что это был ответ. Эти документы генерируются постоянно, поэтому мне придется придумать метод их преобразования, прежде чем импортировать их в db. Кроме того, было бы неплохо сохранить документы в собственном формате. И просто для того, чтобы сделать вещи еще более увлекательными, этот нечетный формат «ключевого элемента» происходит на нескольких уровнях документа. Вздох – FuriousGeorge