As for your problem, you can't really use reduce function to get the total price (as you will do with joins in SQL).
What I suggest you to do is the following :
- Build a view that emits a complex key like this
[invoiceId,{_id:itemId}]
- The view that you just build would also emit the actual invoice for the following key :
[invoiceId, null]
. This way, you get all your informations in one query.
- You query your with with your invoiceId and you locally compute the totalprice. This way, if you update the price of a single item, the totalprice will be updated.
Full example:
Invoice template :
{
"_id": "306860e48b2f6f668c7f409f33000339",
"_rev": "3-73197f590a5d18b2ee01ebc423cacbb6",
"type": "invoice",
"invoiceDate": "11/24/2016",
"customerId": "customer_1",
"invoiceLines": [
{
"quantity": 10,
"item": "item_1"
},
{
"quantity": 8,
"item": "item_2"
}
]
}
Item template
{
"_id": "item_1",
"_rev": "2-879798bd718975fe9957a2a699e041d0",
"type": "item",
"name": "First item",
"price": 1
}
View function
function(doc){
if(doc.type == "invoice"){
emit([doc._id]);
if(doc.invoiceLines){
for(var n in doc.invoiceLines){
var line = doc.invoiceLines[n];
emit([doc._id,line.item],{_id:line.item});
}
}
}
}
Now what should you do?
- Query the view with those parameters ?key=invoiceId&include_docs=true&group_level=1
- Iterates through your data and create a map from the items and assign your invoice to a variable.
- Now in your invoice, for each items, set the total price by multiplying the quantity with the item price.
Other solution
Another way to do it (simplier but in two request)
1. Request the invoice document
2. Request the items with the ids from the invoice document.
3. Compute the total price
Also, you could do this:
When you create an invoice, you could link the item id and compute the total price of the item while creating the document. As it's an invoice, we don't care if the price is updated in the future as it's an invoice (correct me if I'm wrong).