2017-08-11 51 views
0

我的目标是将两个文档链接在一起并取回其详细信息。通过地图功能(CouchDB)连接两个文档的问题

什么是您的CouchDB文档?

汽车

{ 
    "_id": "car.123", 
    "type": "car", 
    "name": "Tesla", 
    "model": "Semi Truck" 
}, 
{ 
    "_id": "car.456", 
    "type": "car", 
    "name": "Tesla", 
    "model": "Roadster" 
} 

厂商

{ 
"_id": "manu.123", 
"type": "manufacturer", 
"name": "Tesla Inc.", 
"cars": ["car.123", "car.456"] 
} 

应该如何,结果是什么样子?

这里我想使用一个List-Function并生成一个HTML表格作为结果。

Name (Manufacturer) | Name (Car) | Model (Car) 
------------------- | ---------- | ---------------- 
Tesla Inc.   | Tesla  | Semi Truck 
Tesla Inc.   | Tesla  | Roadster 

你卡在哪里?

我很难在包围地图函数的时候环顾我的头。这是据我得到了尚未:

function(doc) { 
    if (doc) { 
     // Give me the ID and the name of the manufacturer 
     emit(doc._id, doc.name); 
     // Check if the document has at least one car in its array 
     if (doc.cars < 0) { 
      // Give me for every car their details (eg. name & model) 
      for (var i in doc.cars) { 
       emit(doc.name, {_id: doc.cars[i]}); 
      } 
     } 
    } 
} 

我使用的查询:

ID  | Key  | Value 
-------- | ---------- | --------------- 
manu.123 | Tesla Inc. | [object Object] 
manu.123 | Tesla Inc. | [object Object] 

用这个表:
http://localhost:5984/my-db/_design/my-design/_view/my-view?key="Tesla Inc."&include_docs=true

从列表功能结果功能:

function(head, req){ 
    start({ 
     'headers': { 
      'Content-Type': 'text/html' 
     } 
    }); 
    send('<html><body><table>'); 
    send('<tr><th>ID</th><th>Key</th><th>Value</th></tr>') 
    while(row = getRow()){ 
     send(''.concat(
      '<tr>', 
      '<td>' + row.id + '</td>', 
      '<td>' + row.key + '</td>', 
      '<td>' + row.value + '</td>', 
      '</tr>' 
     )); 
    } 
    send('</table></body></html>'); 
} 

的JSON输出:

{ 
    "total_rows": 10, 
    "offset": 8, 
    "rows": [ 
    { 
     "id": "manu.123", 
     "key": "Tesla Inc.", 
     "value": { 
     "_id": "car.123" 
     }, 
     "doc": { 
     "_id": "car.123", 
     "_rev": "1-7291266e7f81917fef1d0cfa104a39ca", 
     "type": "car", 
     "name": "Tesla", 
     "model": "Semi Truck" 
     } 
    }, 
    { 
     "id": "manu.123", 
     "key": "Tesla Inc.", 
     "value": { 
     "_id": "car.456" 
     }, 
     "doc": { 
     "_id": "car.456", 
     "_rev": "1-c5c67f5d5abeda1b77c02f003ec72a9f", 
     "type": "car", 
     "name": "Tesla", 
     "model": "Roadster" 
     } 
    } 
    ] 
} 

什么是您的具体问题?

如何将[object Object]替换为我车的实际值(例如名称&型号)?


我已经进行了以下的资源,但他们并没有帮助我:
CouchDB's Linked Documents in a View
couchdb views tied between two databases?
combine multiple documents in a couchdb view
Couchdb join two documents using key
CouchDB's Linked Documents in a View
Best way to do one-to-many "JOIN" in CouchDB

回答

1

在你的榜样,row.value等于一个东西,在其中一种情况下:{ "_id": "car.123" }。在JavaScript中,当您尝试连接字符串与对象时,您将获得[object Object],这发生在您的列表函数'<td>' + row.value + '</td>'中。

所以,如果你想显示_id,你可以这样做:'<td>' + row.value._id + '</td>'。但是您要求显示名称型号。纵观json文件,该信息位于doc密钥下。因此,似乎你正在寻找的是:

'<td>' + row.doc.name + ' ' + row.doc.model + '</td>'

1

除了由伊格纳西奥以前的答案,就可以提高你的文档的设计两件事情。

  • 将制造商的_id添加到汽车中,而不是制造商的一系列汽车_id。这样,您不必处理不一致的数据:当您删除汽车文档时,您不必编辑制造商。这在多用户场景中尤为重要。如果一个用户添加一辆汽车,而另一个用户则取出同一制造商的汽车?这可能会导致冲突和不一致的数据。
  • 您还可以通过将制造商的名称添加到汽车文档中来使数据非规范化。这样,你不必加入文件。当数据被大部分读取时(例如在典型的网页或移动应用程序中),CouchDB都非常出色,因此您通常应该优化阅读。此外,map/reduce查询将更容易编写。