如何解决使用MapReduce的CouchDB视图-将来自不同文档的数据减少到一个对象中
我决定对我正在研究的项目使用bedDB。我正在使用ExpressJS在NodeJS中实现服务器,并且正在使用nano作为我的长沙发库。
我有一个简单的用户数据库,其中包含不同类型的用户。本质上,我有3种类型的用户:学生,父母和老师。我决定让学生更容易拥有对父母和老师的推荐。也就是说,数据库中的一个学生文档可能具有两个数组类型的字段,分别称为teachers
和parents
。这两个字段包含老师或家长的电子邮件地址(而每个老师和家长也是数据库中的文档
例如,学生文档可能看起来像这样
{
"name": "student","age" : 17,"email": "student@example.com",//this is also part of the _id for this document
"parents": ["parent1@example.com","parent2@example.com","teacher2@example.com"],//teacher2 is both a parent and teacher of this student
"teachers": ["teacher1@example.com","teacher2@example.com"]
}
父文档看起来像
{
"name": "parent1","age": 45,"email": "parent1@example.com",//this is also part of the _id for this document
}
和教师文档看起来像
{
"name": "teacher1","age": 38,"email": "teacher1@example.com",//this is also part of the _id for this document
}
我要实现的目标
我正在尝试创建一个通过电子邮件地址检索用户的视图。该视图查找具有该特定电子邮件地址的用户并返回该文档。如果该用户是老师或父母,我想浏览数据库中的所有文档并搜索潜在的学生-父母或学生-老师关系。也就是说,如果我正在使用此视图搜索teacher1@example.com
,则我的结果对象应如下所示
{
"name": "teacher1",//this is also part of the _id for this document
"teacherOf" : ["student@example.com"]
}
或者如果我正在搜索parent1@example.com
,结果应该看起来像
{
"name": "parent1",//this is also part of the _id for this document
"parentOf" : ["student@example.com"]
}
甚至有可能,如果父母也是老师并教孩子,那么
{
"name": "teacher2","age": 52,"email": "teacher2@example.com",//this is also part of the _id for this document
"teacherOf" : ["student@example.com"]
"parentOf" : ["student@example.com"]
}
我知道在视图中使用map-reduce是实现此目的的一种可能方法,但是我不确定如何处理。我尝试了几件事。我决定将密钥作为被搜索者的ID发出(因为这似乎是唯一允许使用的密钥),并且该值是一个自定义对象,其中包含有问题的学生的电子邮件地址以及关系:
map: function(doc) {
emit(doc.email,{
name: doc.name,age: doc.age,email: doc.email,teachers: doc.teachers,parents: doc.parents});
(doc.teachers || []).forEach(teacher => {
emit( teacher,{studentEmail: doc.email,relationship: 'teacher'});
});
(doc.parents || []).forEach(parent => {
emit( parent,relationship: 'parent'});
});
},reduce: function(key,values) {
return values;
}
此视图称为all_details
然后我有一个简单的Node函数,该函数使用nano来调用此视图
testFindAllDetails(email) {
return this._usersDB.view('_users','all_details',{
key: email
});
}
当我按当前状态调用此视图时,例如,调用testFindAllDetails('teacher2@example.com')
时,得到的结果看起来像
{
"rows": [
{
"key": null,"value": [
[
{
"name": "teacher2",}
],[
{
"studentEmail": "student@example.com","relationship": "teacher"
},{
"studentEmail": "student@example.com","relationship": "parent"
}
]
]
}
]
}
我的问题是,如何使用我的reduce
函数将该结果合并到一个对象中?我的map
成功地检索了在其'teacher2@example.com'
或parents
字段中拥有该电子邮件的所有学生,即teachers
,但是我不确定如何使用{视图的{1}}部分将其全部合并为一个对象。
对于它的价值,如果我摆脱了视图的约简部分并运行相同的功能reduce
,这就是我的结果。
testFindAllDetails('teacher2@example.com')
总结一下,问题是如何将结果组合成类似这样的内容
{
"total_rows": 20,"offset": 2,"rows": [
{
"id": "org.couchdb.user:teacher2@example.com","key": "teacher2@example.com","value": {
"name": "teacher2","email": "teacher2@example.com"
}
},{
"id": "org.couchdb.user:student@example.com","value": {
"studentEmail": "student@example.com","relationship": "teacher"
}
},"relationship": "parent"
}
}
]
}
其中创建了两个新字段 {
"name": "teacher2",//this is also part of the _id for this document
"teacherOf" : ["student@example.com"]
"parentOf" : ["student@example.com"]
}
和teacherOf
,这些字段是由所有可能与此老师或父母有关系的学生组成的数组。
btw,如果通过学生电子邮件(例如parentOf
)调用了相同的功能,则结果可能包含也可能不包含testFindAllDetails('student@example.com')
和teacherOf
字段,但是如果确实包含它们,他们可以为空数组也可以。例如
parentOf
在此先感谢您的帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。