The trick with this is get away from thinking in terms of JOINs. Linked documents give you a technique to index one type of document based on properties of another. This works using a combination of two features:
- CouchDB allows you to specify include_docs=true when querying a view to return the indexed documents along with the view results.
- You can tell CouchDB to return ANY document by specifying an _id property in the view result. Note that you can still only return one document per result.
As an example, lets say you had documents
{
"_id": "111",
"type", "shoe",
"sku": "656F-PINSEC12",
"shoe-color": "black/houndstooth",
"imageId": "222"
}
and
{
"_id": "222",
"type": "image",
"full-images": ["http://www.someurl.com/full/656F-PINSEC12.jpg"]
"thumbnail-images": ["http://www.someurl.com/thumb/656F-PINSEC12.jpg"]
}
then you could index images by SKU using the map function:
function(doc) {
if(doc.type === "shoe") {
emit(doc.sku, {_id: doc.imageId });
}
}
It's also important to realise that the map function only operates on the original document that was saved.
I think in your example, the "catalog item" and "shoe color" documents are redundant. You could define a map function to index the "shoe image" and "shoe size" documents by SKU e.g.
function(doc) {
if(doc.SKU) {
emit(doc.SKU, null);
}
}
Assuming this was assigned to the view "item-details", your query:
should return
{
"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
}
]
}
]
}
If you wanted to combine these results into a single JSON document, you could look at using a list function to generate custom JSON output. However, I'm not sure that gains you much.
It looks like you'd generally be better off with a more granular data model (e.g. each shoe / size combination could be a separate doc) and use map functions to aggregate the data for a given SKU.