2015-08-23 4 views
1

У меня есть документ, MongoDB, который имеет записи, выглядит следующим образом:Как группировать записи по полю в Mongoose?

[ 
    { _id: id, category_name: 'category1', parent_category: null }, 
    { _id: id, category_name: 'category2', parent_category: null }, 
    { _id: id, category_name: 'subcategory1', parent_category: id_parent_1 }, 
    { _id: id, category_name: 'subcategory2', parent_category: id_parent_1 }, 
    { _id: id, category_name: 'subcategory3', parent_category: id_parent_2 }, 
    { _id: id, category_name: 'subcategory4', parent_category: id_parent_2 } 
] 

Как вы можете видеть, я храню категории с parent_category из null и подкатегорий имеют идентификатор родительской категории в. То, что я ищу, чтобы сгруппировать их в какое-то формат, как это:

[ 
    { category_name: 'category1', categories: [ 
     { category_name: 'subcategory1', _id: id }, 
     { category_name: 'subcategory2', _id: id } 
    ] 
    }, 
    { category_name: 'category2', categories: [ 
     { category_name: 'subcategory3', _id: id }, 
     { category_name: 'subcategory4', _id: id } 
    ] 
    } 
] 

Так в основном групповой родительские категории с массивом с их дочерними категориями. Я использую Mongoose. Я попытался использовать структуру агрегации MongoDB, но я не могу получить желаемый результат. :(

У меня есть доступ для изменения схемы любого способа, который может быть необходим!

Заранее спасибо!

+0

Почему вы проектировали свой документ таким образом в первую очередь? возможно, вы можете перепроектировать схему mongoose и сделать некоторые методы для проверки parent_id для назначения подкатегорий –

+0

Это всего лишь два уровня категорий? могут ли ваши подкатегории иметь свои подкатегории? – yarons

+0

@JoseOsorio Я не совсем понимаю, что вы имеете в виду – pmerino

ответ

2

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

var CategorySchema = new Schema({ 
    category_name: String, 
    subCategories:[subCategorySchema] 
} 

var subCategorySchema = new Schema({ 
    category_name: String 
}) 

Таким образом, когда вам нужно запросить коллекции это просто

db.find({category_name: "name of the category"}, function(){}) 

, чтобы получить все необходимое.

На всякий случай: вы можете добавить подкатегории в массив с простыми обновлениями. Читайте this для получения дополнительной информации.

+0

Пришлось немного изменить это мои потребности, но в целом это то, что мне нужно. Благодаря! – pmerino

1

Пожалуйста, попробуйте это, если Ваша схема не изменилась:

var MongoClient = require('mongodb').MongoClient 

//connect away 
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) { 
    if (err) throw err; 
    console.log("Connected to Database"); 

    //simple json record 
    var document = []; 
    //insert record 
    //db.data.find({"parent_category":null }).forEach(function(data) {print("user: " + db.data.findOne({"parent_category":data._id })) }) 
    db.collection('data').find({"parent_category":null }, function(err, parentrecords) { 
     if (err) throw err; 
     var cat ={}; 
     parentrecords.forEach(function(data){ 
      cat["category_name"] = data["category_name"]; 
      db.collection('data').find({"parent_category":data._id },function(err, childrecords) { 
       var doc = []; 
       childrecords.forEach(function(childdata){ 
        doc.push(childdata); 
         },function(){ 
         cat["categories"] = doc; 
         document.push(cat); 
         console.log(document); 
        }); 
      }); 
     }); 
}); 
}); 
-1

Для того, чтобы сгруппировать записи по полю попробуйте использовать $ группу в Aggreegation .Это работал для меня.

Пример

db.categories.aggregate(
    [ 
    { $group : { _id : {category_name:"$category_name"}, categories: { $push: {category_name:"$category_name",_id:"$_id"} } } } 
    ] 
) 

Ссылка: MongoDB Aggregation

Надеется, что это работает.

1

Если вы хотите узнать ожидаемые результаты без изменения схемы, вы в основном следуете сложному запросу mongo aggregation. Для нахождения выхода я следую следующие шаги:

  1. Первый в $project проверка parent_category равна null, если так, то добавить еще _id добавить parent_category.
  2. Теперь структура документа выглядит как новый key name as parent_id представляет и группирует parent_id и нажимает оставшиеся данные, такие как category_name and parent_category.
  3. После этого использования $setDifference и $setIntersection дифференцировать родительские данные и данные ребенка.
  4. И, наконец, unwind только объекты с одним массивом, поэтому этот единственный объект массива и используемый проект отображают только те поля, которые отображаются.

Проверить работает агрегация запрос, как показано ниже:

db.collectionName.aggregate({ 
    "$project": { 
     "parent_id": { 
      "$cond": { 
       "if": { 
        "$eq": ["$parent_category", null] 
       }, 
       "then": "$_id", 
       "else": "$parent_category" 
      } 
     }, 
     "category_name": 1, 
     "parent_category": 1 
    } 
}, { 
    "$group": { 
     "_id": "$parent_id", 
     "categories": { 
      "$push": { 
       "category_name": "$category_name", 
       "parent_category": "$parent_category" 
      } 
     }, 
     "parentData": { 
      "$push": { 
       "$cond": { 
        "if": { 
         "$eq": ["$parent_category", null] 
        }, 
        "then": { 
         "category_name": "$category_name", 
         "parent_category": "$parent_category" 
        }, 
        "else": null 
       } 
      } 
     } 
    } 
}, { 
    "$project": { 
     "findParent": { 
      "$setIntersection": ["$categories", "$parentData"] 
     }, 
     "categories": { 
      "$setDifference": ["$categories", "$parentData"] 
     } 
    } 
}, { 
    "$unwind": "$findParent" 
}, { 
    "$project": { 
     "category_name": "$findParent.category_name", 
     "categories": 1 
    } 
}).pretty() 
Смежные вопросы