CouchDB:链接引用不同文档类型数组的文档

CouchDB:链接引用不同文档类型数组的文档,couchdb,cloudant,Couchdb,Cloudant,说到CouchDB,我是个新手。我来自.NETSQLServer世界 在浏览CouchDB的权威指南时,我像是“呜呜呜呜,这太棒了”。现在我正在测试我学到的一些东西,希望在现实世界中实现它 几周前,我刚刚注册了一个Cloudant帐户,并开始使用它进行一些测试/学习 在处理相关文件时,背后的整个理论看起来很简单,同时也是互联网上的前卫例子。我想从一个有不同链接文档数组的文档中检索一些信息,这些文档本身有链接文档数组。就像连接到多对多关系表的多SQL Server一样。你会看到下面的代码。希望这是

说到CouchDB,我是个新手。我来自.NETSQLServer世界

在浏览CouchDB的权威指南时,我像是“呜呜呜呜,这太棒了”。现在我正在测试我学到的一些东西,希望在现实世界中实现它

几周前,我刚刚注册了一个Cloudant帐户,并开始使用它进行一些测试/学习

在处理相关文件时,背后的整个理论看起来很简单,同时也是互联网上的前卫例子。我想从一个有不同链接文档数组的文档中检索一些信息,这些文档本身有链接文档数组。就像连接到多对多关系表的多SQL Server一样。你会看到下面的代码。希望这是有道理的

以这个SQL查询为例。假设每个表中只有一个条目,我们应该返回一条记录,其中包含给定sku鞋子的所有详细信息。但是如果我们有多个鞋码,我们就必须编写更多的代码

select ci.sku
        ,sc.color
        ,ss.size
        ,si.url
from CatalogItem ci
    join ShoeImages si
        on ci.sku = si.sku
        and ci.sku = '656F-PINSEC12'
    join ShoeSizes ss
        on ci.sku = ss.sku
    join ShoeColors sc
        on ci.sku = sc.sku
我希望CouchDB通过SKU返回以下JSON

鉴于以下文件和地图/地图:

//--catalog item
{
   "_id": "689fe6982f4d604541db67ee4050a535",
   "_rev": "5-64b5ddd751c51aadfcef1962c2c99c16",
   "type": "catalogue-item",
   "sku": "656F-PINSEC12",
   "upc": "8549875231",
   "shoe-colors": [
       {
           "_id": "bbbb92c3d61ed9f4f0e8111fb20fcf43",
           "shoe-images": [
               {
                   "_id": "7b547bae4ac911c6f05b97eba6cb355a"
               }
           ],
           "shoe-sizes": [
               {
                   "_id": "12b6289d558d7ceb5bef725091666ce5"
               }
           ]
       }
   ]
}

//--shoe images
{
   "_id": "7b547bae4ac911c6f05b97eba6cb355a",
   "_rev": "4-4fde0cac1b4b8afc618bbba5b6669193",
   "type": "shoe-images",
   "sku": "656F-PINSEC12",
   "color": "Black/Houndstoot",
   "full-images": [
       "http://www.someurl.com/full/656F-PINSEC12.jpg"
   ],
   "thumbnail-images": [
       "http://www.someurl.com/thumb/656F-PINSEC12.jpg"
   ]
}

//--shoe color
{
   "_id": "bbbb92c3d61ed9f4f0e8111fb20fcf43",
   "_rev": "2-e5d07c00a0261c231dd2be9b26a6c0dc",
   "type": "shoe-color",
   "sku": "656F-PINSEC12",
   "color": "black/houndstooth"
}

//--shoe sizes
{
   "_id": "12b6289d558d7ceb5bef725091666ce5",
   "_rev": "2-192df709f9de1ef27e9e5f4404863bcc",
   "type": "shoe-sizes",
   "sku": "656F-PINSEC12",
   "shoe-color": "black/houndstooth",
   "shoe-sizes": [
       {
           "size": 5,
           "IsSizeAvailable": true
       },
       {
           "size": 6,
           "IsSizeAvailable": true
       },
       {
           "size": 7,
           "IsSizeAvailable": true
       },
       {
           "size": 8,
           "IsSizeAvailable": true
       },
       {
           "size": 9,
           "IsSizeAvailable": true
       },
       {
           "size": 10,
           "IsSizeAvailable": true
       },
       {
           "size": 11,
           "IsSizeAvailable": true
       },
       {
           "size": 12,
           "IsSizeAvailable": true
       },
       {
           "size": 13,
           "IsSizeAvailable": true
       },
       {
           "size": 14,
           "IsSizeAvailable": true
       }
   ]
}

//--map/reduce
{
   "_id": "_design/catalog",
   "_rev": "4-de5baf04b485768de12d78e5a0e5aa5e",
   "views": {
       "item": {
           "map": "function(doc) 
                {
                  if (doc.type === 'catalog-item') 
                  {
                    emit([doc.sku, doc], null);
                    if (doc.shoe-colors) 
                    {
                      for (var sc in doc.shoe-colors) 
                      {
                        emit([doc.sku, Number(sc)+1], {_id: doc.shoe-colors[sc]._id});
                        for (var si in doc.shoe-colors[sc].shoe-images) 
                        {
                            emit([doc.sku, Number(si)+1], {_id: doc.shoe-colors[sc].shoe-images[si]._id});
                        }
                        for (var sz in doc.shoe-colors[sc].shoe-sizes) 
                        {
                            emit([doc.sku, Number(sz)+1], {_id: doc.shoe-colors[sc].shoe-sizes[sz]._id});
                        }
                      }
                    }
                  }
                }"
       }
   }
}
也许有更好的方法来实现这一点,但我想看看是否有可能拥有一个包含链接文档数组的文档,而这些文档也包含一个链接文档数组。但是我的map/reduce没有返回任何内容。它的回报是:

{"total_rows":0,"offset":0,"rows":[

]}
我猜有些人不会将所有信息存储在一个文档中,因为,假设我们添加一个新的show size或将鞋码标记为notavailable,这意味着只需更新一个字段,就必须将所有以前的值传递回CouchDB


希望我的问题有意义,这样做的诀窍是从连接的角度出发。链接文档为您提供了一种基于另一种文档的属性为一种类型的文档编制索引的技术。这将使用两个功能的组合来工作:

  • CouchDB允许您在查询视图时指定include_docs=true,以返回索引文档以及视图结果
  • 通过在视图结果中指定_id属性,可以告诉CouchDB返回任何文档。请注意,每个结果仍然只能返回一个文档
  • 例如,假设您有文档

    {
         "_id": "111",
         "type", "shoe",
         "sku": "656F-PINSEC12",
         "shoe-color": "black/houndstooth",
         "imageId": "222"
    }
    

    然后,您可以使用映射功能按SKU索引图像:

    function(doc) {
         if(doc.type === "shoe") {
             emit(doc.sku, {_id: doc.imageId });
         }
    }
    
    同样重要的是要认识到map函数只对保存的原始文档起作用

    我认为在您的示例中,“目录项”和“鞋色”文档是多余的。您可以定义映射函数,以按SKU索引“鞋图像”和“鞋尺寸”文档,例如

    function(doc) {
        if(doc.SKU) {
            emit(doc.SKU, null);
        }
    }
    
    假设已将其分配给“项目详细信息”视图,则您的查询:

    应该回来

    {
       "total_rows":2,
       "offset":0,
       "rows":
       [
           {
              "id":"7b547bae4ac911c6f05b97eba6cb355a",
              "key":"656F-PINSEC12",
              "value":null,
              "doc":{
                 "_id": "7b547bae4ac911c6f05b97eba6cb355a",
                 "_rev": "4-4fde0cac1b4b8afc618bbba5b6669193",
                 "type": "shoe-images",
                 "sku": "656F-PINSEC12",
                 "color": "Black/Houndstoot",
                 "full-images": [
                     "http://www.someurl.com/full/656F-PINSEC12.jpg"
                 ],
                 "thumbnail-images": [
                      "http://www.someurl.com/thumb/656F-PINSEC12.jpg"
                 ]
              }
          },
          {
              "id":"12b6289d558d7ceb5bef725091666ce5",
              "key":"656F-PINSEC12",
              "value":null
              "doc":{
                "_id": "12b6289d558d7ceb5bef725091666ce5",
               "_rev": "2-192df709f9de1ef27e9e5f4404863bcc",
               "type": "shoe-sizes",
               "sku": "656F-PINSEC12",
               "shoe-color": "black/houndstooth",
               "shoe-sizes": [
                   {
                       "size": 5,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 6,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 7,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 8,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 9,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 10,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 11,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 12,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 13,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 14,
                       "IsSizeAvailable": true
                   }
               ]
    
            }       
        ] 
    }
    
    如果您想将这些结果合并到一个JSON文档中,可以考虑使用生成自定义JSON输出。然而,我不确定这会给你带来多少好处


    看起来,使用更细粒度的数据模型(例如,每个鞋子/尺码组合可以是一个单独的文档)并使用映射函数来聚合给定SKU的数据通常会更好。

    “wut wut这太棒了”非常感谢您给出的非常有启发性的答案。帮助很大。
    function(doc) {
        if(doc.SKU) {
            emit(doc.SKU, null);
        }
    }
    
    {
       "total_rows":2,
       "offset":0,
       "rows":
       [
           {
              "id":"7b547bae4ac911c6f05b97eba6cb355a",
              "key":"656F-PINSEC12",
              "value":null,
              "doc":{
                 "_id": "7b547bae4ac911c6f05b97eba6cb355a",
                 "_rev": "4-4fde0cac1b4b8afc618bbba5b6669193",
                 "type": "shoe-images",
                 "sku": "656F-PINSEC12",
                 "color": "Black/Houndstoot",
                 "full-images": [
                     "http://www.someurl.com/full/656F-PINSEC12.jpg"
                 ],
                 "thumbnail-images": [
                      "http://www.someurl.com/thumb/656F-PINSEC12.jpg"
                 ]
              }
          },
          {
              "id":"12b6289d558d7ceb5bef725091666ce5",
              "key":"656F-PINSEC12",
              "value":null
              "doc":{
                "_id": "12b6289d558d7ceb5bef725091666ce5",
               "_rev": "2-192df709f9de1ef27e9e5f4404863bcc",
               "type": "shoe-sizes",
               "sku": "656F-PINSEC12",
               "shoe-color": "black/houndstooth",
               "shoe-sizes": [
                   {
                       "size": 5,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 6,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 7,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 8,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 9,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 10,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 11,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 12,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 13,
                       "IsSizeAvailable": true
                   },
                   {
                       "size": 14,
                       "IsSizeAvailable": true
                   }
               ]
    
            }       
        ] 
    }