有没有办法扩展存储在数据库中的对象?
例子:
假设我有一个对象:
{
id: 1
extends: null
type: HondaAccord
doors: 4
engine: 2 liter
dealerId: null
price: 20000
}
第二个对象扩展了第一个
{
id: 2
extends: 1
dealerId: 2
price: 25000
key1: value1
key2: value2
}
第三个对象结束第二个:
{
id: 3
extends: 2
dealerId: 3
price: 27000
key1: some extended value
}
我希望能够查询第二个对象并返回:
{
id: 2
extends: 1
type: HondaAccord
doors: 4
engine: 2 liter
dealerId: 2
price: 25000
key1: value1
key2: value2
}
我希望能够查询第三个对象并返回:
{
id: 3
extends: 2
type: HondaAccord
doors: 4
engine: 2 liter
dealerId: 3
price: 27000
key1: some extended value
key2: value2
}
在关系数据库中,我可以规范化这些数据并做一些复杂的左连接等来获得它。
在 NoSQL 数据库中是否有更简单的方法来执行此操作?我的应用程序要求我能够查询这些对象并取回文字表示以及扩展的(如预期结果所示)表示。
目前,我正在使用 Java 代码执行此操作。即:获取一个对象,查看它是否应该扩展另一个对象,获取该对象并递归遍历它。如果我需要能够抓取大量“展开的”对象,则会出现严重的性能问题。
有什么模式可以创建这样的东西吗? SQL 还是 NoSQL?看起来几乎像装饰器模式,但用于数据。
最佳答案
$graphlookup
操作递归匹配集合中的“extends”和“id”属性,并返回每个查询文档的层次结构。
申请$sort
由于无法保证查找到的数据保持顺序,因此我们可以有序地解决重复键。
使用当前 (3.4) 产品版本。
使用$arrayToObject
和 $objectToArray
在$reduce
与 $concatArrays
合并文档。
$objectToArray
为当前 ($$this
) 和 $$value
生成具有键值对的数组以连接所有键值对生成一个键值对数组,然后是 $arrayToObject
以生成合并的文档和 $replaceRoot
提升为顶级文档。
$sort
按“id”desc
和“扩展”desc
优先选择查询文档中的字段而不是其他查找文档。
db.collection.aggregate([
{
"$match": {
"id": 3
}
},
{
"$graphLookup": {
"from": collection,
"startWith": "$id",
"connectFromField": "extends",
"connectToField": "id",
"as": "hierarchy"
}
},
{
"$unwind": "$hierarchy"
},
{
"$sort": {
"id": -1,
"hierarchy.extends": 1
}
},
{
"$group": {
"_id": "$id",
"hierarchy": {
"$push": "$hierarchy"
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$reduce": {
"input": "$hierarchy",
"initialValue": [],
"in": {
"$concatArrays": [
{
"$objectToArray": "$$this"
},
"$$value"
]
}
}
}
}
}
}
])
您可以使用 mergeObjects
聚合运算符在当前开发版本 3.5.13 开发版本中可用,该开发版本将集成到即将发布的 3.6 版本中。
$sort
按“id”desc
和“扩展”asc
优先选择查询文档中的字段而不是其他查找文档。
db.collection.aggregate([
{
"$match": {
"id": 3
}
},
{
"$graphLookup": {
"from": collection,
"startWith": "$id",
"connectFromField": "extends",
"connectToField": "id",
"as": "hierarchy"
}
},
{
"$unwind": "$hierarchy"
},
{
"$sort": {
"id": -1,
"hierarchy.extends": -1
}
},
{
"$group": {
"_id": "$id",
"hierarchy": {
"$push": "$hierarchy"
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$reduce": {
"input": "$hierarchy",
"initialValue": {},
"in": {
"$mergeObjects": [
"$$this",
"$$value"
]
}
}
}
}
}
])
关于sql - 扩展存储在数据库中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46759399/