我认为这就是我要找的那个词。我正在尝试将父信息输入每张卡片。我认为这就是我需要做的事情,但如果你有任何其他想法,请加入。
{
"LEA": {
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core",
"cards": [
{"name": "Air Elemental"},
{"name": "Earth Elemental"},
{"name": "Fire Elemental"},
{"name": "Water Elemental"}
]
},
"LEB": {
"name": "Limited Edition Beta",
"code": "LEB",
"releaseDate": "1993-10-01",
"border": "black",
"type": "core",
"cards": [
{"name": "Armageddon"},
{"name": "Fireball"},
{"name": "Swords to Plowshares"},
{"name": "Wrath of God"}
]
}
}
显然,这是数据的一小部分。 LEA
和LEB
是卡片组,每组中都有一堆卡片。我正在考虑将这种非正规化为卡片,并将设置信息添加到每张卡片中。像这样......
{
{
"name": "Air Elemental",
"set": {
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core"
}
},
{
"name": "Earth Elemental",
"set": {
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core"
}
},
{
"name": "Armageddon",
"set": {
"name": "Limited Edition Beta",
"code": "LEB",
"releaseDate": "1993-10-01",
"border": "black",
"type": "core"
}
},
{
"name": "Fireball",
"set": {
"name": "Limited Edition Beta",
"code": "LEB",
"releaseDate": "1993-10-01",
"border": "black",
"type": "core"
}
}
}
我的想法是否正确,首先是?我想要一个巨大的cards
集合,并将设置的信息展平到每张卡片中吗?在SQL中,我会为这些集做一个表,并且这些卡会belong_to
一组。我试图围绕'文档思考'。
其次,如果我的想法是正确的,关于如何实现这种非规范化的任何想法?
答案 0 :(得分:1)
这里你去=)。
好的,这是我要去的地方。由于我们已经说卡片永远不会改变(因为它们基于物理MTG卡),所以创建一个包含所有卡片的集合,这将用于以后轻松填充用户的卡片。您可以使用卡片名称或某种卡片ID(如存储在卡片上的物理卡片ID)进行搜索。
对于用户的卡片对象数组,您不应只存储卡片的_id
字段,因为这会强制您加入。由于卡片永远不会改变,因此完全非规范化它们并将它们推入该卡片阵列中,因此到目前为止,用户对象类似于:
{
name: "Tom Hanks",
skill_level: 0,
decks: [
[
{
card_name: "Balance",
card_description: "LONG_BLOCK_OF_DESCRIP_TEXT",
card_creator: "Sugargirl14",
type: "Normal",
_id: $SOME_MONGO_ID_HERE,
... rest of card data...
}, {
...card 2 complete data...
}
],
[
{ ...another deck here... }
]
]
}
好的,回到设置信息,我也会假设设置信息是一个常数(基于你的SO帖子,我看不出它会如何改变)。因此,如果该集合信息始终与卡片相关,我会将其归一化并包含它,将我们的卡片对象更改为:
{
card_name: "Balance",
card_description: "LONG_BLOCK_OF_DESCRIP_TEXT",
card_creator: "Sugargirl14",
type: "Normal",
_id: $SOME_MONGO_ID_HERE
set: {
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core",
"_id": $SOME_MONGO_ID_HERE
},
... rest of card data...
}
我认为将其他卡存储在给定卡的非规范化对象中是不相关的,如果是,则添加它们。如果你注意到,你的SO示例中给出的密钥将被删除,因为它似乎总是==“代码”字段。
好的,现在要正确回答你关于是否应该将卡片嵌入卡片的问题,反之亦然。首先,两个集合都是相关的。因此,即使我们将集合嵌入到卡片中,您也会希望将这些集合放入集合中,以便以后可以将其取出并插入新卡片中。
嵌入的内容实际上取决于业务逻辑,数据的使用方式以及更频繁的数据。您是否经常展示套装并从中拉出卡片(例如用户搜索)?您可以在每个集合的cards
数组中嵌入所有卡数据或任何相关数据。但是使用上述数据模型,每张卡都将其设置ID存储在其设置对象中。我假设卡片只属于一套,所以要获得一套卡片,你可以在卡片集合中查询你想要的set.id == the Mongo ID
集合。由于业务逻辑,现在需要最少的更新(希望根本没有),并且您的查询仍然很快(并且您获得完整的卡对象)。老实说,我会做那个后者,并保持我的设置清洁卡。因此,卡拥有其所属的集合,而非拥有卡。这是一种更为SQL的方式,认为它实际上可以在Mongo中正常工作(你永远不会加入)。
所以我们的最终数据模型类似于:
Collection 1,Set:
//data model
{
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core",
"_id": $SOME_MONGO_ID_HERE
}
收集2,卡片:
//data model
{
_id: $SOME_MONGO_ID_HERE
card_name: "Balance",
card_description: "LONG_BLOCK_OF_DESCRIP_TEXT",
card_creator: "Sugargirl14",
type: "Normal",
set: {
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core",
"_id": $SOME_MONGO_ID_HERE
... rest of card data...
},
}
收藏3,用户:
{
_id: $SOME_MONGO_ID_HERE,
name: "Tom Hanks",
skill_level: 0,
decks: [
[
{
card_name: "Balance",
card_description: "LONG_BLOCK_OF_DESCRIP_TEXT",
card_creator: "Sugargirl14",
type: "Normal",
_id: $SOME_MONGO_ID_HERE,
set: {
"name": "Limited Edition Alpha",
"code": "LEA",
"releaseDate": "1993-08-05",
"border": "black",
"type": "core",
"_id": $SOME_MONGO_ID_HERE
},
}, {
...card 2 complete data...
}
],
[
{ ...another deck here... }
]
]
}
这显然假设每张卡的设定数据与用户相关。现在你的数据被非规范化,集合和卡很少需要更新(根据业务逻辑),所以你永远不需要级联更新或删除。操纵用户很容易。当您从用户的牌组中移除一张牌时,您可以在相关的牌组数据上从Mongo(我认为这就是所谓的)执行$pull
,其中包含项目的_id
字段== Mongo ID你要删除的卡。所有其他更新都更容易。
回想起来,您可能希望像这样制作用户的套牌:
decks: {
"SOME_ID_HERE": [
{ ...card 1... },
{ ...card 2... }
]
}
这使得识别甲板变得更容易,并且可以使您的拉动变得更容易(您将在前端获得更多数据,并且拉取查询将更加精确)。它可以是一个数字,随机字符串,任何真正的东西,因为它被传递回前端。或者只是使用他们的Mongo ID,当看到牌组时,用户将拥有它的Mongo ID。然后,当他们从中拉出一张卡片,或者添加一张卡片时,你就有了一个直接的标识符,可以轻松抓住所需的卡片。
显然所有带有文本的值如:$ MONGO_ID_HERE应该是MongoId()对象。
哇,那是激烈的,6800个字符。希望它对你有意义,如果任何措辞令人困惑或我的任何JSON对象的格式被搞砸了,我都会道歉(只是让我知道如果任何散文令人困惑,我会改写)。这是否有意义/解决您的问题?