sql - 扩展存储在数据库中的对象

标签 sql mongodb nosql

有没有办法扩展存储在数据库中的对象?

例子:

假设我有一个对象:

{
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/

相关文章:

mysql - 查询以获得最近的游戏结果

java - 有没有办法将 HQL 与 MongoDB 结合使用?

c# - ASP.NET MVC3 和 MongoDB

nosql - Cassandra中节点和分区的区别

elasticsearch - 如何从索引(具有多种类型)的搜索中获取每种类型的前1个文档?

sql - 如何在T-SQL中翻转位域?

SQL 日期时间到字符串格式

C# IOptions 无法将我的对象隐式转换为接口(interface)以将其注入(inject)我的服务 AddSingleton

MongoDB 使用 MapReduce 交叉连接集合

javascript - 是否有由 HTML + css + javascript 支持的 sql 编辑器?