'CouchDB View, list key with duplicate count
In CouchDB I have a collection of articles. Each article has a tags property. I wrote this map function to list all tags in database
function (doc) {
for(var i = 0; i < doc.metaKeywords.length; i++)
emit(doc.metaKeywords[i], 1)
}
But when it list all tags, it show duplicates of tags. I want to show only one time for each tag and show duplicate number of each tags instead of emit duplicate rows of same key.
What should I do to modify this map function?
Solution 1:[1]
The map function is OK, but there is no reason to emit the value 1.
Regardless, the simple builtin reduce function _count and the right query does everything required.
Working with CouchDB demands understanding the B-tree and it's documentation has a great rundown of it in its Reduce/Rereduce documentation. I highly recommend grok'ing that information.
The snippet below highlights its usage via pouchdb. The design document specifies both map and reduce, e.g.
{
"_id": "_design/SO-72078037",
"views": {
"tags": {
"map": `function (doc) {
if(doc.tags) doc.tags.forEach(tag => emit(tag));
}`,
"reduce": "_count",
}
}
}
Straight forward stuff. To get key (tag) counts the query is as simple:
{
reduce: true,
include_docs: false,
group_level: 1
}
Again, the CouchDB documentation is great - read up on group level queries
const gel = id => document.getElementById(id);
async function showReduceDocs(view) {
let result = await db.query(view, {
reduce: true,
include_docs: false,
group_level: 1
});
// show
gel('view_reduce').innerText = result.rows.map(row => JSON.stringify(row))
.join('\n');
}
async function showViewDocs(view) {
let result = await db.query(view, {
reduce: false,
include_docs: false
});
gel('view_docs').innerText = result.rows.map(row => JSON.stringify(row))
.join('\n');
}
function getDocsToInstall() {
return [{
tags: ["A", "B", "C"]
},
{
tags: ["A", "B"]
},
{
tags: ["A"]
},
{
// design document
"_id": "_design/SO-72078037",
"views": {
"tags": {
"map": `function (doc) {
if(doc.tags) doc.tags.forEach(tag => emit(tag));
}`,
"reduce": "_count",
}
}
},
];
}
const db = new PouchDB('SO-72078037', {
adapter: 'memory'
});
(async() => {
// install docs and show view in various forms.
await db.bulkDocs(getDocsToInstall());
showReduceDocs('SO-72078037/tags');
showViewDocs('SO-72078037/tags');
})();
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
<div>View: Reduce</div>
<pre id='view_reduce'></pre>
<hr/>
<div>View</div>
<pre id='view_docs'></pre>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
