CouchDB 视图,列出具有重复计数的键
CouchDB View, list key with duplicate count
我在 CouchDB 中收集了一系列文章。每篇文章都有一个标签属性。
我写了这个地图函数来列出数据库中的所有标签
function (doc) {
for(var i = 0; i < doc.metaKeywords.length; i++)
emit(doc.metaKeywords[i], 1)
}
但是当它列出所有标签时,它会显示重复的标签。我只想为每个标签显示一次,并显示每个标签的重复数量,而不是发出相同键的重复行。
这个地图功能怎么修改?
map
函数没问题,但没有理由发出值 1。
无论如何,简单的内置 reduce 函数 _count
和正确的查询可以完成所需的一切。
使用 CouchDB 需要理解 B-tree,它的文档在其 Reduce/Rereduce 文档中有一个很好的概述。我强烈建议您仔细阅读该信息。
下面的代码片段突出显示了它通过 pouchdb 的用法。设计文档同时指定 map
和 reduce
,例如
{
"_id": "_design/SO-72078037",
"views": {
"tags": {
"map": `function (doc) {
if(doc.tags) doc.tags.forEach(tag => emit(tag));
}`,
"reduce": "_count",
}
}
}
直截了当的东西。要获取键(标签)计数,查询非常简单:
{
reduce: true,
include_docs: false,
group_level: 1
}
同样,CouchDB 文档很棒 - 请继续阅读 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/pouchdb@7.1.1/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>
我在 CouchDB 中收集了一系列文章。每篇文章都有一个标签属性。 我写了这个地图函数来列出数据库中的所有标签
function (doc) {
for(var i = 0; i < doc.metaKeywords.length; i++)
emit(doc.metaKeywords[i], 1)
}
但是当它列出所有标签时,它会显示重复的标签。我只想为每个标签显示一次,并显示每个标签的重复数量,而不是发出相同键的重复行。
这个地图功能怎么修改?
map
函数没问题,但没有理由发出值 1。
无论如何,简单的内置 reduce 函数 _count
和正确的查询可以完成所需的一切。
使用 CouchDB 需要理解 B-tree,它的文档在其 Reduce/Rereduce 文档中有一个很好的概述。我强烈建议您仔细阅读该信息。
下面的代码片段突出显示了它通过 pouchdb 的用法。设计文档同时指定 map
和 reduce
,例如
{
"_id": "_design/SO-72078037",
"views": {
"tags": {
"map": `function (doc) {
if(doc.tags) doc.tags.forEach(tag => emit(tag));
}`,
"reduce": "_count",
}
}
}
直截了当的东西。要获取键(标签)计数,查询非常简单:
{
reduce: true,
include_docs: false,
group_level: 1
}
同样,CouchDB 文档很棒 - 请继续阅读 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/pouchdb@7.1.1/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>