带有 _id 数组的 MongoDB 关系数据结构 [英] MongoDB Relational Data Structures with array of _id's

查看:63
本文介绍了带有 _id 数组的 MongoDB 关系数据结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经使用 MongoDB 有一段时间了,有一件事我无法理解.假设我有一组用户,这些用户有这样的监视列表或收藏夹列表:

We have been using MongoDB for some time now and there is one thing I just cant wrap my head around. Lets say I have a a collection of Users that have a Watch List or Favorite Items List like this:

usersCollection = [
    {
        _id: 1,
        name: "Rob",
        itemWatchList:[
            "111111",
            "222222",
            "333333"
        ]

    }
];

和一个单独的项目集合

itemsCollection = [
    {
        _id:"111111",
        name: "Laptop",
        price:1000.00
    },
    {
        _id:"222222",
        name: "Bike",
        price:123.00
    },
    {
        _id:"333333",
        name: "House",
        price:500000.00
    }
];

显然我们不想在 itemWatchList 数组中插入整个 item obj,因为 items 数据可能会改变,即价格.

Obviously we would not want to insert the whole item obj inside the itemWatchList array because the items data could change i.e. price.

假设我们将该用户拉到 GUI 并希望显示用户 itemWatchList 的网格.我们不能,因为我们只有一个 ID 列表.是执行第二个 collection.find([itemWatchList]) 然后在结果回调中操作用户记录以显示当前项目的唯一选择吗?问题是如果我返回一个由多个用户组成的数组,每个用户都有一个 itemWatchList 的数组,那将是一个回调噩梦,试图保持结果直截了当.我知道 Map Reduce 或 Aggregation 框架不能遍历多个集合.

Lets say we pull that user to the GUI and want to diplay a grid of the user itemWatchList. We cant because all we have is a list of ID's. Is the only option to do a second collection.find([itemWatchList]) and then in the results callback manipulate the user record to display the current items? The problem with that is what if I return an array of multiple Users each with an array of itemWatchList's, that would be a callback nightmare to try and keep the results straight. I know Map Reduce or Aggregation framework cant traverse multiple collections.

这里的最佳实践是什么?是否有更好的数据结构可以用来避免这个问题?

What is the best practice here and is there a better data structure that should be used to avoid this issue all together?

推荐答案

关于如何显示关系数据,您有 3 个不同的选项.它们都不是完美的,但您选择的那个可能不是您用例的最佳选择.

You have 3 different options with how to display relational data. None of them are perfect, but the one you've chosen may not be the best option for your use case.

选项 1 - 引用 ID这是您选择的选项.保留一个 Id 列表,通常在要引用的对象数组中.稍后要显示它们,您使用 $in 查询进行第二次往返.

Option 1 - Reference the IDs This is the option you've chosen. Keep a list of Ids, generally in an array of the objects you want to reference. Later to display them, you do a second round-trip with an $in query.

选项 2 - 子文档对于您的情况,这可能是一个糟糕的解决方案.这意味着将存储在 items 集合中的整个文档数组作为子文档放入您的用户集合中.如果一次只有一个用户可以拥有一个项目,这很好.(例如,不同的送货地址和账单地址.)

Option 2 - Subdocuments This is probably a bad solution for your situation. It means putting the entire array of documents that are stored in the items collection into your user collection as a sub-document. This is great if only one user can own an item at a time. (For example, different shipping and billing addresses.)

选项 3 - 组合这可能是您的最佳选择,但这意味着更改您的架构.例如,假设您的商品有 20 个属性,但您实际上只关心大多数屏幕的名称和价格.然后你有一个这样的架构:

Option 3 - A combination This may be the best option for you, but it'll mean changing your schema. For example, lets say that your items have 20 properties, but you really only care about the name and price for the majority of your screens. You then have a schema like this:

usersCollection = [
    {
        _id: 1,
        name: "Rob",
        itemWatchList:[
            {
                _id:"111111",
                name: "Laptop",
                price:1000.00
            },
            {
                _id:"222222",
                name: "Bike",
                price:123.00
            },
            {
                _id:"333333",
                name: "House",
                price:500000.00
            }
        ]
    }
];

itemsCollection = [
    {
        _id:"111111",
        name: "Laptop",
        price:1000.00,
        otherAttributes: ...
    },
    {
        _id:"222222",
        name: "Bike",
        price:123.00
        otherAttributes: ...
    },
    {
        _id:"333333",
        name: "House",
        price:500000.00,
        otherAttributes: ...
    }
];

困难在于您必须使这些项目彼此同步.(这就是最终一致性的意思.)如果你有一个低风险的应用程序(不是银行、医疗保健等),这没什么大不了的.您可以让两个更新查询连续发生,将拥有该商品的用户更新为新价格.如果您注意,您会在某些网站上注意到这种延迟.例如,即使您返回并刷新搜索结果,Ebay 在搜索结果页面上的价格通常与您打开实际页面后的实际价格不同.

The difficulty is that you then have to keep these items in sync with each other. (This is what is meant by eventual consistency.) If you have a low-stakes application (not banking, health care etc) this isn't a big deal. You can have the two update queries happen successively, updating the users that have that item to the new price. You'll notice this sort of latency on some websites if you pay attention. Ebay for example often has different prices on the search results pages than the actual price once you open the actual page, even if you return and refresh the search results.

祝你好运!

这篇关于带有 _id 数组的 MongoDB 关系数据结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆