2010-05-25 57 views
3

在MySQL我使用JOIN和一个查询是没有问题的。那么mongo呢?mongoDB多对多一个查询?

想象类别和产品。

产品可能有更多类别。 类别可能有更多产品。 (多对多结构) 和管理员可以在管理中编辑类别(类别必须分开)

其可能在一个查询中写入具有类别名称的产品?

我用这个结构

categories { 
    name:"categoryName", 
     product_id:["4b5783300334000000000aa9","5783300334000000000aa943","6c6793300334001000000006"] 
} 


products { 
    name:"productName", 
category_id:["4b5783300334000000000bb9","5783300334000000000bb943","6c6793300334001000000116"] 
} 

现在我可以简单地让所有的产品类别和产品在某些类别和单独类别editation。但是如果我想用类别名称编写产品,我需要两个查询 - 一个用于获取产品类别ID,另一个用于通过该ID从类别获取类别名称。

这是正确的方法吗?或者这种结构不合适?我想只有一个查询,但我不知道它是否可能。

回答

4

是的,MongoDB在这种特殊类型的操作中特别糟糕。但是,这也是一个范围问题。如果您有3000万个产品,并且您希望将300万个产品加入到他们的类别中,您会发现它在许多数据库中并不是很快(即使它只是一行代码)。

MongoDB在这里需要的是一些非规范化。

您的收藏可能会是这样的:

categories { 
    _id:"mongoid", 
    name:"categoryName", 
    ... 
} 

products { 
    _id:"mongoid", 
    name:"productName", 
    categories:[ 
    {"4b5783300334000000000bb9":'categoryName'}, 
    {"5783300334000000000bb943":'CategoryName2'}, 
    {"6c6793300334001000000116":'categoryName3'} 
    ] 
} 

下面是它如何工作(粗略估计,没有我的蒙戈实例方便):

抓斗产品及其类别

db.products.find({"_id": {$in:[1,2,3]}, {name:1,categories:1})

获取某产品分类的产品:

db.products.find({"categories.0": {$in:[x,y,z]}},{categories:1,name:1} }

是的,它不完全相同。当您更改类别的名称时,您必须必须更新全部的产品记录。我知道这看起来很奇怪,但这是非规范化的标准。

顺便说一句,我假设你会有很多产品和少得多的类别。如果你在每个类别中说100个项目,这种方法可能是最好的。如果每个类别中有5个项目,那么您可能需要在每个项目中存储更多的类别信息。

1

是的,这是你拥有的唯一方法。没有加入的可能性。

但是你可以在你的类别或产品文档像增添了不少的信息:

categories { 
    name:"categoryName", 
     product_id:[ {"4b5783300334000000000aa9": 'productName'},{"5783300334000000000aa943":'productName2'},{"6c6793300334001000000006":'productName3'}] 
} 


products { 
    name:"productName", 
category_id:[{"4b5783300334000000000bb9":'categoryName'},{"5783300334000000000bb943":'CategoryName2',{"6c6793300334001000000116":'categoryName3'}] 
} 

但你需要做一些回调更新所有稿件时的变化。