连接MongoDB两表联接实现数据查询
MongoDB是一个开源的文档型数据库,用于处理大型数据。它不仅提供了高效的数据存储、查询和分析功能,而且可以在分布式系统中进行水平扩展。在实际项目中,需要对两个或多个表中的数据进行关联查询,这时就需要使用MongoDB中的联接(join)操作。
1. MongoDB联接操作介绍
在MongoDB中,联接操作主要有以下两种方式:
嵌套文档
引用文档
其中,嵌套文档是将一个文档嵌套在另一个文档中,这种方式适用于一对一或一对多的关系。而引用文档是将两个文档通过一个公共字段关联起来,这种方式适用于多对多的关系。
2. MongoDB两表联接实现数据查询
假设有两个文档,一个是用户表(users),包含了用户的基本信息;另一个是订单表(orders),包含了用户的订单信息。我们想要查询用户所有的订单信息,就需要对用户表和订单表进行联接操作。
db.users.insertMany([
{name: "Tom", age: 26, sex: "male", phone: "123456789"},
{name: "Lucy", age: 22, sex: "female", phone: "987654321"}
]);
db.orders.insertMany([
{user_id: 1, order_no: "001", order_time: "2022-05-01 10:00:00", amount: 100},
{user_id: 2, order_no: "002", order_time: "2022-05-01 11:00:00", amount: 200},
{user_id: 1, order_no: "003", order_time: "2022-05-02 10:00:00", amount: 50},
{user_id: 2, order_no: "004", order_time: "2022-05-02 11:00:00", amount: 150}
]);
上述代码中,我们先向用户表和订单表中插入了一些数据。其中,用户表中的每个文档包含了用户的名称、年龄、性别和手机号码,订单表中的每个文档包含了用户编号、订单号、订单时间和订单金额。
3. MongoDB引用文档联接实现数据查询
在上述例子中,我们可以使用引用文档的方式来实现用户表和订单表的联接。具体实现步骤如下:
在用户表中添加一个字段(如_id),用于关联订单表中的user_id字段。
查询用户表和订单表中的数据,使用$lookup操作将两个表进行关联。
使用$project操作对结果进行处理,去掉_id字段和user_id字段。
下面是具体的实现代码:
db.users.aggregate([
{
$lookup:
{
from: "orders",
localField: "_id",
foreignField: "user_id",
as: "orders"
}
},
{
$project:
{
_id: 0,
user_id: 0,
"orders.user_id": 0
}
}
]);
上述代码中,我们使用了$lookup操作将用户表和订单表进行联接,关联字段分别为_id和user_id。$project操作则去掉了_id字段和orders中的user_id字段,最终得到的结果如下:
{
"name" : "Tom",
"age" : 26,
"sex" : "male",
"phone" : "123456789",
"orders" : [
{
"order_no" : "001",
"order_time" : "2022-05-01 10:00:00",
"amount" : 100
},
{
"order_no" : "003",
"order_time" : "2022-05-02 10:00:00",
"amount" : 50
}
]
},
{
"name" : "Lucy",
"age" : 22,
"sex" : "female",
"phone" : "987654321",
"orders" : [
{
"order_no" : "002",
"order_time" : "2022-05-01 11:00:00",
"amount" : 200
},
{
"order_no" : "004",
"order_time" : "2022-05-02 11:00:00",
"amount" : 150
}
]
}
上述结果中,我们可以看到每个用户对应了他的所有订单信息,通过这种方式实现了两个表的关联查询。
4. MongoDB嵌套文档联接实现数据查询
在实际项目中,有时候嵌套文档的方式更适合进行联接操作。假设我们现在有两个文档,一个是商品表(products),包含了商品的基本信息;另一个是订单表(orders2),包含了用户购买商品的订单信息。我们想要查询每个订单中购买的商品详细信息,就需要对商品表和订单表进行嵌套文档的联接操作。
db.products.insertMany([
{name: "iPhone X", price: 8000},
{name: "MacBook Pro", price: 15000},
{name: "iPad mini", price: 3000},
{name: "Apple Watch", price: 2000}
]);
db.orders2.insertMany([
{user_id: 1, order_no: "001", order_time: "2022-05-01 10:00:00",
products: [
{product_id: 1, quantity: 2},
{product_id: 2, quantity: 1}
]
},
{user_id: 2, order_no: "002", order_time: "2022-05-01 11:00:00",
products: [
{product_id: 2, quantity: 1},
{product_id: 3, quantity: 3}
]
},
{user_id: 1, order_no: "003", order_time: "2022-05-02 10:00:00",
products: [
{product_id: 3, quantity: 1},
{product_id: 4, quantity: 2}
]
},
{user_id: 2, order_no: "004", order_time: "2022-05-02 11:00:00",
products: [
{product_id: 1, quantity: 1},
{product_id: 3, quantity: 2},
{product_id: 4, quantity: 1}
]
}
]);
上述代码中,我们先向商品表和订单表中插入了一些数据。其中,商品表中的每个文档包含了商品的名称和价格,订单表中的每个文档包含了用户编号、订单号、订单时间和购买的商品数量和商品编号。
我们可以使用以下代码实现商品表和订单表的嵌套文档联接操作:
db.orders2.aggregate([
{
$lookup:
{
from: "products",
localField: "products.product_id",
foreignField: "_id",
as: "product_list"
}
},
{
$project:
{
_id: 0,
user_id: 1,
order_no: 1,
order_time: 1,
"product_list.name": 1,
"product_list.price": 1,
"products.quantity": 1
}
}
]);
上述代码中,我们使用了$lookup操作将商品表和订单表进行联接,关联字段分别为products.product_id和_id。$project操作则对结果进行处理,去掉了_id字段,展示了购买商品的用户编号、订单号、订单时间、产品名称、产品价格和购买数量,最终的查询结果如下:
{
"user_id" : 1,
"order_no" : "001",
"order_time" : "2022-05-01 10:00:00",
"product_list" : [
{
"name" : "iPhone X",
"price" : 8000
},
{
"name" : "MacBook Pro",
"price" : 15000
}
],
"products" : [
{
"product_id" : 1,
"quantity" : 2
},
{
"product_id" : 2,
"quantity" : 1
}
]
},
...
上述结果中,我们可以看到每个订单对应了其中所购买的商品信息,通过这种方式实现了两个表的关联查询。
总结
在MongoDB中,联接操作主要有嵌套文档和引用文档两种方式。嵌套文档适用于一对一或一对多的关系,而引用文档则适用于多对多的关系。在实际项目中,需要对两个或多个表中的数据进行关联查询,使用联接操作可以很好地解决这个问题。