连接MongoDB两表联接实现数据查询

连接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中,联接操作主要有嵌套文档和引用文档两种方式。嵌套文档适用于一对一或一对多的关系,而引用文档则适用于多对多的关系。在实际项目中,需要对两个或多个表中的数据进行关联查询,使用联接操作可以很好地解决这个问题。

数据库标签