NoSql RavenDb数据设计-生成的最大地图问题

NoSql RavenDb数据设计-生成的最大地图问题,ravendb,nosql,Ravendb,Nosql,我们使用RavenDb作为NoSql数据存储。我们将存储大量需要高性能查询的数据 我们当前的关系模型被转换为文档结构,我将使用不相关的类名,因为我无法披露真实的业务案例: 公司 拥有自己的属性,并包含商店列表(大约50家) 贮藏 有自己的属性,并包含产品列表(约150个) 产品 它有自己的属性 我们将其存储为Json: { "Id": 1, "CompanyName": "first company", "Location": "Not so far", "Store

我们使用RavenDb作为NoSql数据存储。我们将存储大量需要高性能查询的数据

我们当前的关系模型被转换为文档结构,我将使用不相关的类名,因为我无法披露真实的业务案例:

  • 公司
拥有自己的属性,并包含商店列表(大约50家)

  • 贮藏
有自己的属性,并包含产品列表(约150个)

  • 产品
它有自己的属性

我们将其存储为Json:

{
  "Id": 1,
  "CompanyName": "first company",
  "Location": "Not so far",
  "Stores": [
      {
        "Id": 125,
        "CompanyId": 1,
        "StoreName": "sweets",
        "Products": [
            {
              "Id": 1289,
              "StoreId": 125,
              "Name": "Candy",
              "Price" : 10
            }
        ]
      }
    ]
}
我们希望使用OData服务公开文档的每个子列表

我们向所选级别添加了一个索引映射,但随后出现了一个RavenDb错误,即每个文档只允许15个映射输出


我们也可以存储最低级别(产品)并复制所有存储和公司数据。但这似乎是一个糟糕的设计。

如果您知道业务案例的子文档的最大数量,您可以通过在索引定义上设置以下属性来覆盖最大索引结果的限制:

         MaxIndexOutputsPerDocument = 150; 

您正在创建所谓的扇出索引,RavenDB默认情况下将扇出数限制为15。这在一定程度上是由于扇出索引很难通过db来优化性能

在您的情况下,看起来您将为每个“公司”存储一个文档,其中包含公司的所有存储,每个存储包含所有产品。如果确实如此,文档可能相当大,如果文档中的某些内容被多人同时修改,可能会导致并发问题

考虑将公司存储为一个文档,其中包含对其每个存储的Id引用

{
    "Id": "Companies/1",
    "CompanyName": "first company",
    "Location": "Not so far",
    "Stores": [
            "Stores/1",
            "Stores/2"
        ]
}  
每个商店(也是单独的文档)都有对每个产品的引用:

{
    "Id": "Stores/1",
    "CompanyId": "Companies/1",
    "StoreName": "sweets",
    "Products": [
        "Products/1",
        "Products/2"
    ]
}
产品(也是单独的文档)保留对其存储的引用(如果一个产品只能在一个存储中,如您的示例中所示):

现在,您可以创建任何类型的索引,如
Products\u ByStore
Stores\u ByCompany
等。如果您决定将CompanyId直接存储在产品上,也可以执行
Products\u ByStore\u和ByCompany
(或者在产品索引中使用LoadDocument加载商店并映射商店公司id,但如果可能,请尽量避免)

如果您希望以与json示例相同的形式返回某些内容,您可以在CompanyId上执行LoadDocument,并使用
ResultTransformer
,在服务器上加载所有商店及其所有产品并返回所有内容。然而,这可能是一个相当“昂贵”的过程操作,基于一家公司拥有多少商店和产品,但至少是服务器端(有点像SQL中的连接)

不要害怕在像Raven这样的文档数据库中使用关系,但要考虑如何使用关系。如果您经常加载一家公司并希望按名称列出所有商店,则可以将关系按id与有关商店的更多信息(如名称)相结合。文档可能如下所示:

{
    "Id": "Companies/1",
    "CompanyName": "first company",
    "Location": "Not so far",
    "Stores": [
            { "Id": "Stores/1", "Name": "sweets" },
            { "Id": "Stores/2", "Name": "another store name" }
        ]
}  
现在商店名称是重复的,如果商店文档中发生更改,当然也必须在公司文档中进行更新

和往常一样,这要视情况而定。希望这至少能给你一些帮助

//J

{
    "Id": "Companies/1",
    "CompanyName": "first company",
    "Location": "Not so far",
    "Stores": [
            { "Id": "Stores/1", "Name": "sweets" },
            { "Id": "Stores/2", "Name": "another store name" }
        ]
}