我有一个关系数据模型我正在考虑迁移到MongoDB或CouchDB,我试图了解查询是如何工作的 . 假设我有两个实体,Employees和Projects,以及一个名为Assignments的多对多连接表 . 我想查询两个用户合作的所有项目 . 在SQL中,我可以这样做:
SELECT DISTINCT a1.project_id
FROM assignments a1, assignments a2
WHERE a1.project_id = a2.project_id
AND a1.employee_id = ?
AND a2.employee_id = ?
假设我有Employee,Project和Assignment“文档”,我将如何在NoSQL中执行此操作?或者你会以不同的方式构建文档,这会如何影响查询?
我很高兴听到Mongo的查询API和Couch的map / reduce方法的答案 .
3 回答
我只能分享沙发的观点,我,嗯,每隔一段时间放松一下 . 首先,在处理基于文档的系统时,您几乎总是有意忘记SQL .
其次,您可以选择更改结构并将实体数量减少到不需要连接的最小值,或者您可以使用将不同类型的文档组合到单个结果集中的视图 .
前者(重新设计)是首选方法,因为连接本质上是nosql的外来方法,因为规范化不是那里的要求 . 基于文档不是关系型的 .
在MongoDB中,你可以这样做 . 我使用交互式JavaScript Shell .
首先创建一些用户:
现在创建一些项目
将用户添加到项目中
如果你现在想要找到所有项目“Joe”
找到Joe OR Moe工作的所有项目
找到Joe AND moe工作的所有项目
要获得特定项目的所有雇员,您需要两个查询 . 从项目C中寻找所有员工 .
在您的应用程序中,您可以根据返回值构建新查询并构建此查询:
我希望这有助于理解MongoDB如何工作以及如何 Build 关系 . 我在这里使用手动解除引用 . 这意味着我直接保存ObjectID并手动获取它 . 还存在“DBRef”,然后您的驱动程序会为您获取它 .
您正在寻找的是有效的N:M映射 . 在这种情况下,您尝试将表映射到自身,但这与尝试将“Employees”映射到“Projects”没有太大区别 .
有一个很长的答案over here关于我,我不会在这里重复 .
在您的具体情况下,我认为您需要重新设计一些数据 . 您有一个包含两个数据点的
assignments
表:projectID
和employeedID
. 这是将N个项目加入M员工的经典表格 .在MongoDB中,通常根本没有"table" . 如果要将员工分配给项目,则只需在项目本身中存储
employeeID
数组 .看起来您的查询基本上是"find all projects where employee 2 and 3 are working together" . MongoDB有一个$all query operator,它将通过上述结构为您完成此操作 .
请注意,这只是一个查询 . 在进行模式设计时,重要的是要查看整个系统并确定 all 重要查询 .