gpt4 book ai didi

javascript - CouchDB View 使用来自两个单独文档的嵌入式数组组成 JSON 对象

转载 作者:数据小太阳 更新时间:2023-10-29 06:08:54 24 4
gpt4 key购买 nike

假设我的 CouchDB 数据库中存储了两种类型的文档。第一个是属性类型设置为 contact,第二个是 phone。联系人类型文档有另一个名为名称的属性。电话类型有属性 number 和 contact_id 以便它可以引用联系人。这是一个简单的一对多场景,其中一个联系人可以有 N 个电话号码(我知道它们可以嵌入到单个联系人文档中,但我需要证明与不同文档的一对多关系)。

原始示例数据,其中 Scott 有 2 个电话号码,Matt 有 1 个电话号码:

{_id: "fc93f785e6bd8c44f14468828b001109", _rev: "1-fdc8d121351b0f5c6d7e288399c7a5b6", type: "phone", number: "123456", contact_id: "fc93f785e6bd8c44f14468828b00099f"}
{_id: "fc93f785e6bd8c44f14468828b000f6a", _rev: "1-b2dd90295693dc395019deec7cbf89c7", type: "phone", number: "465789", contact_id: "fc93f785e6bd8c44f14468828b00099f"}
{_id: "fc93f785e6bd8c44f14468828b00099f", _rev: "1-bd643a6b0e90c997a42d8c04c5c06af6", type: "contact", name: "Scott"}
{_id: "16309fcd03475b9a2924c61d690018e3", _rev: "1-723b7c999111b116c353a4fdab11ddc0", type: "contact", name: "Matt"}
{_id: "16309fcd03475b9a2924c61d69000aef", _rev: "3-67193f1bfa8ed21c68e3d35847e9060a", type: "phone", number: "789456", contact_id: "16309fcd03475b9a2924c61d690018e3"}

map 功能:

function(doc) {
if (doc.type == "contact") {
emit([doc._id, 1], doc);
} else if (doc.type == "phone") {
emit([doc.contact_id, 0], doc);
}
}

归约函数:

function(keys, values) {
var output = {};

for(var elem in values) {
if(values[elem].type == "contact") {
output = {
"ID": values[elem]._id,
"Name": values[elem].name,
"Type": values[elem].type,
"Phones": []
};
} else if (values[elem].type == "phone") {
output.Phones.push({
"Number": values[elem].number,
"Type": values[elem].type
});
}
}

return output;
}

由于 Map 函数中的键,group_level 设置为 1。现在我可以通过包含的电话获取我的联系人,例如:

http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1

或者像这样用 startkey 和 endkey 搜索一些联系人:

http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1&startkey=[%22fc93f785e6bd8c44f14468828b00099f%22]&endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,{}]

结果看起来正是我想要的 - 联系人将根据一对多关系具有嵌入式电话。问题来了:这是在 CouchDB 中使用 MapReduce 函数的正确方法吗?使用这种方法时是否存在任何明显的性能问题?

最佳答案

一般来说,如果您不emit(...,doc),您使用的磁盘空间会更少。

您可能想要重新考虑是否使用 reduce 函数。确实没有必要获取您需要的数据。例如,如果您有大量记录,则以下内容可能会使用更少的磁盘空间并且性能更好。

此外,我认为在 reduce 函数中构建比文档包含的数据更多的数据有悖于 CouchDB 的原则。在这种情况下,您没有这样做,但您遵循的模式可能会在以后给您带来麻烦。它被称为 reduce 是有原因的。 :-)

所以像这样的东西更像是 CouchDB 的方式:

function(doc) {
if (doc.type == "contact") {
emit([doc._id, 0], {
"Name": doc.name,
"Type": doc.type
});
} else if (doc.type == "phone") {
emit([doc.contact_id, 1], {
"Number": doc.number,
"Type": doc.type
});
}
}

像这样查询特定联系人:

http://localhost:5984/testdb2/_design/testview/_view/tv1?  startkey=[%22fc93f785e6bd8c44f14468828b00099f%22, 0]  &endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,1]

当然,您不会获得与以前相同的 JSON 结构的结果,但我相信这在 CouchDB 中表现更好。

关于javascript - CouchDB View 使用来自两个单独文档的嵌入式数组组成 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3353059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com