Reputation: 3
Let's say we have the following data structure:
{
"name": "",
"tags": []
}
With the following example data:
{
"name": "Test1",
"tags": [
"Laptop",
"Smartphone",
"Tablet"
]
}
{
"name": "Test2",
"tags": [
"Computer",
"Laptop",
"Smartphone",
"Tablet"
]
}
{
"name": "Test3",
"tags": [
"Smartphone",
"Tablet"
]
}
Now I am trying to find: Find all documents with with Smartphone AND Tablet in tags. This should return all documents.
I can't figure out how this works with couchdb. I tried to add the tags as keys and played with startkey / endkey with no luck.
Hope somebody can help me out.
Greetings, Ben
Upvotes: 0
Views: 324
Reputation: 1792
I see two possible solutions. Why don't you have a view with a map function like:
function(doc) {
doc.tags && doc.tags.forEach(function(tag) {
emit(tag, null);
});
}
Now if you query this view with keys=["Smartphone", "Tablet"] you will get the following lines:
{id: "A", key: "Smartphone", value: null},
{id: "B", key: "Smartphone", value: null},
{id: "C", key: "Smartphone", value: null},
{id: "A", key: "Tablet", value: null},
{id: "B", key: "Tablet", value: null},
{id: "C", key: "Tablet", value: null}
Now you have to parse this response well on the client side, to filter out the ids which don't show up for all the keys of your query. In this case all the documents (A, B, C) show up, so this is your result. Once you have it, you can use bulk get to fetch the values with:
POST http://...:../db/_all_docs?include_docs=true
with keys=["A", "B", "C"]
This is how I'd do it.
The second approach you could use, is to have a map function which emits all possible subsets of the doc.tags. (Find all possible subset combos in an array?). With the index structure like this, you can get the desired documents with a single query simply using:
key=["Smartphone", "Tablet"] and include_docs=true.
However keep in mind that this means emitting 2**n (n - number of tags) rows for you view, so use this approach only if you are sure that there is only few of them for each doc.
Upvotes: 1