在mongodb中设计模式

时间:2016-07-19 10:21:12

标签: mongodb

想象一下,我有两个架构:类别和产品。现在我需要一个名为lists的第三个模式。管理员可以创建具有多个类别的列表,而类别又将具有多个产品。

另外一个类别可以在多个列表中,一个产品可以在任意数量的类别中。我总是使用以下方式创建一个模式。

lists: {
   _id: '1',
   name: 'list 1',
   categories: [{
       categoryId: '201',
       products: [
           {
              productId: '301',
              name: 'product 1'
           },
           {
              productId: '302',
              name: 'product 2'
           }
       ]
   },
   {
       categoryId: '202',
       products: [
           {
              productId: '302',
              name: 'product 2'
           },
           {
              productId: '304',
              name: 'product 4'
           }
       ]           
   }]
}

问题在于,如果我必须从类别中删除产品,我必须遍历所有产品并找到产品并将其删除。当我只需要查询一个产品或一个类别时,我必须这样做。有没有更好的方法来创建列表架构?

2 个答案:

答案 0 :(得分:0)

如果执行<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <label class="tmpcpa">32.1</label> aggregate阵列,则无需循环显示结果。看看那个查询:

unwind

会将您的数组转换为json对象:

db.device.aggregate([{
    "$unwind": "$categories"
},{
    "$unwind": "$categories.products"
}])

根据您的喜好结合一些比赛,您可以轻松获得特定的结果。以下内容仅为您提供包含特定{ "_id" : "1", "name" : "list 1", "categories" : { "categoryId" : "201", "products" : { "productId" : "301", "name" : "product 1" } } } { "_id" : "1", "name" : "list 1", "categories" : { "categoryId" : "201", "products" : { "productId" : "302", "name" : "product 2" } } } { "_id" : "1", "name" : "list 1", "categories" : { "categoryId" : "202", "products" : { "productId" : "302", "name" : "product 2" } } } { "_id" : "1", "name" : "list 1", "categories" : { "categoryId" : "202", "products" : { "productId" : "304", "name" : "product 4" } } } { "_id" : "2", "name" : "list 2", "categories" : { "categoryId" : "201", "products" : { "productId" : "303", "name" : "product 3" } } } { "_id" : "2", "name" : "list 2", "categories" : { "categoryId" : "201", "products" : { "productId" : "304", "name" : "product 4" } } } { "_id" : "2", "name" : "list 2", "categories" : { "categoryId" : "202", "products" : { "productId" : "302", "name" : "product 2" } } } { "_id" : "2", "name" : "list 2", "categories" : { "categoryId" : "202", "products" : { "productId" : "304", "name" : "product 4" } } } &amp;的记录。 categories.categoryId

categories.products.productId

给你:

db.device.aggregate([{
    "$unwind": "$categories"
},{
    "$unwind": "$categories.products"
}, {
    $match: {
        "categories.categoryId": "201",
        "categories.products.productId": "301"
    }
}])

您可以按{ "_id": "1", "name": "list 1", "categories": { "categoryId": "201", "products": { "productId": "301", "name": "product 1" } } } 或其他任何内容添加$group密钥。看https://docs.mongodb.com/manual/aggregation/

要删除子数组_id的项目,也不需要循环显示结果,使用products请求和update,您可以在数组中找到您想要的内容并在一个请求中删除它。

在以下请求中,我使用pull,其结果由pull定义,因为您在另一个数组中有一个数组:

elemMatch

上述查询只会删除包含db.device.update({ 'categories': { '$elemMatch': { categoryId: '201' } }, _id: '1' }, { $pull: { 'categories.$.products': { 'productId': '301' } } }); 201 productId 201和元素匹配categoryId

的元素

检查https://docs.mongodb.com/manual/reference/operator/update/pull/

答案 1 :(得分:0)

是的,如果您不想使用列表获取categoriesproducts,则可以像通常使用SQL数据库一样设计架构。像这样:

List
      {
           '_id':1,
           'name': 'groceries'  
        }

Category
    {
      '_id':1,
      'listId': 1,
      'name': 'Cereal'
    }
Product
    {
      '_id': 1,
      'name': 'Weetbix',
      'categoryId':1
    }

这样做可以帮助您轻松管理数据。