欢迎光临
我们一直在努力

MongoDB(44)什么是引用?

在MongoDB中,引用(Reference)是一种在文档之间建立关系的方式。与嵌入式文档不同,引用是通过存储其他集合中文档的标识符来建立关系。这种方式类似于SQL中的外键,适用于需要多个独立集合之间建立关系的场景。

引用的特点

  • 分离数据:引用将相关数据分离到不同的集合中,有助于减少数据冗余。
  • 独立更新:引用允许独立更新相关数据,而不需要更新整个文档。
  • 适合一对多和多对多关系:引用特别适用于复杂的数据模型,比如一对多和多对多关系。

使用引用的示例

以下示例展示了如何在MongoDB中使用引用。我们将使用Node.js和MongoDB的驱动进行操作。

安装MongoDB的Node.js驱动

npm install mongodb

插入包含引用的数据

const { MongoClient, ObjectId } = require('mongodb');

async function insertData() {
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri, { useUnifiedTopology: true });

try {
await client.connect();
const db = client.db('myDatabase');
const usersCollection = db.collection('users');
const ordersCollection = db.collection('orders');

await usersCollection.deleteMany({}); // 清空用户集合
await ordersCollection.deleteMany({}); // 清空订单集合

// 插入用户数据
const users = await usersCollection.insertMany([
{ name: "Alice" },
{ name: "Bob" },
{ name: "Charlie" }
]);

// 插入订单数据,并使用用户的ObjectId作为引用
await ordersCollection.insertMany([
{ userId: users.insertedIds[0], amount: 50.5, date: new Date("2022-01-01") },
{ userId: users.insertedIds[0], amount: 100.0, date: new Date("2022-02-01") },
{ userId: users.insertedIds[1], amount: 75.0, date: new Date("2022-01-15") },
{ userId: users.insertedIds[2], amount: 200.0, date: new Date("2022-03-01") }
]);

console.log("Data inserted");
} finally {
await client.close();
}
}

insertData().catch(console.error);

在上面的代码中,orders 集合中的每个文档都包含一个 userId 字段,该字段引用了 users 集合中的用户文档的 _id。

查询包含引用的数据

async function queryData() {
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri, { useUnifiedTopology: true });

try {
await client.connect();
const db = client.db('myDatabase');
const usersCollection = db.collection('users');
const ordersCollection = db.collection('orders');

// 查询某个用户及其所有订单
console.log("\\nQuery a user and their orders:");
let user = await usersCollection.findOne({ name: "Alice" });
let orders = await ordersCollection.find({ userId: user._id }).toArray();
console.log({ user, orders });

// 查询所有订单及其对应的用户信息
console.log("\\nQuery all orders and their corresponding users:");
let results = await ordersCollection.aggregate([
{
$lookup: {
from: 'users', // 要关联的集合
localField: 'userId', // orders 集合中的字段
foreignField: '_id', // users 集合中的字段
as: 'user' // 输出数组字段
}
},
{
$unwind: '$user' // 展开数组
}
]).toArray();
console.log(results);

} finally {
await client.close();
}
}

queryData().catch(console.error);

在这个示例中,我们演示了如何查询包含引用的数据:

  • 查询某个用户及其所有订单。
  • 查询所有订单及其对应的用户信息。
  • 运行这个脚本后,你会得到如下结果(示例输出):

    // 查询某个用户及其所有订单
    Query a user and their orders:
    {
    user: { _id: new ObjectId("…"), name: 'Alice' },
    orders: [
    { _id: new ObjectId("…"), userId: new ObjectId("…"), amount: 50.5, date: 20220101T00:00:00.000Z },
    { _id: new ObjectId("…"), userId: new ObjectId("…"), amount: 100, date: 20220201T00:00:00.000Z }
    ]
    }

    // 查询所有订单及其对应的用户信息
    Query all orders and their corresponding users:
    [
    {
    _id: new ObjectId("…"),
    userId: new ObjectId("…"),
    amount: 50.5,
    date: 20220101T00:00:00.000Z,
    user: { _id: new ObjectId("…"), name: 'Alice' }
    },
    {
    _id: new ObjectId("…"),
    userId: new ObjectId("…"),
    amount: 100,
    date: 20220201T00:00:00.000Z,
    user: { _id: new ObjectId("…"), name: 'Alice' }
    },
    {
    _id: new ObjectId("…"),
    userId: new ObjectId("…"),
    amount: 75,
    date: 20220115T00:00:00.000Z,
    user: { _id: new ObjectId("…"), name: 'Bob' }
    },
    {
    _id: new ObjectId("…"),
    userId: new ObjectId("…"),
    amount: 200,
    date: 20220301T00:00:00.000Z,
    user: { _id: new ObjectId("…"), name: 'Charlie' }
    }
    ]

    其他语言示例

    类似的操作可以在其他编程语言中实现,如Python。以下是Python的示例代码:

    安装PyMongo

    在终端中运行以下命令来安装PyMongo:

    pip install pymongo

    插入数据

    from pymongo import MongoClient
    from datetime import datetime

    def insert_data():
    client = MongoClient('mongodb://localhost:27017/')
    db = client['myDatabase']
    users_collection = db['users']
    orders_collection = db['orders']

    users_collection.delete_many({}) # 清空用户集合
    orders_collection.delete_many({}) # 清空订单集合

    # 插入用户数据
    users = users_collection.insert_many([
    { "name": "Alice" },
    { "name": "Bob" },
    { "name": "Charlie" }
    ])

    # 插入订单数据,并使用用户的ObjectId作为引用
    orders_collection.insert_many([
    { "userId": users.inserted_ids[0], "amount": 50.5, "date": datetime(2022, 1, 1) },
    { "userId": users.inserted_ids[0], "amount": 100.0, "date": datetime(2022, 2, 1) },
    { "userId": users.inserted_ids[1], "amount": 75.0, "date": datetime(2022, 1, 15) },
    { "userId": users.inserted_ids[2], "amount": 200.0, "date": datetime(2022, 3, 1) }
    ])

    print("Data inserted")

    insert_data()

    查询数据

    def query_data():
    client = MongoClient('mongodb://localhost:27017/')
    db = client['myDatabase']
    users_collection = db['users']
    orders_collection = db['orders']

    # 查询某个用户及其所有订单
    print("\\nQuery a user and their orders:")
    user = users_collection.find_one({ "name": "Alice" })
    orders = list(orders_collection.find({ "userId": user['_id'] }))
    print({ "user": user, "orders": orders })

    # 查询所有订单及其对应的用户信息
    print("\\nQuery all orders and their corresponding users:")
    pipeline = [
    {
    '$lookup': {
    'from': 'users', # 要关联的集合
    'localField': 'userId', # orders 集合中的字段
    'foreignField': '_id', # users 集合中的字段
    'as': 'user' # 输出数组字段
    }
    },
    {
    '$unwind': '$user' # 展开数组
    }
    ]
    results = list(orders_collection.aggregate(pipeline))
    for result in results:
    print(result)

    query_data()

    赞(0)
    未经允许不得转载:171主机测评 » MongoDB(44)什么是引用?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址