Node.js CouchDB使用MapReduce查看-将不同文档中的数据缩减为一个对象

Node.js CouchDB使用MapReduce查看-将不同文档中的数据缩减为一个对象,node.js,mapreduce,couchdb,couchdb-nano,Node.js,Mapreduce,Couchdb,Couchdb Nano,我决定将couchDB用于我正在进行的一个项目。我正在使用ExpressJS在NodeJS中实现一个服务器,并将其用作我的coach库 我有一个简单的用户数据库,包含不同类型的用户。基本上,我有三种类型的用户:学生、家长和老师。我决定让学生们更容易找到他们父母和老师的推荐信。i、 e数据库中的学生文档可能有两个类型为数组的字段,分别称为teachers和parents。这两个字段拥有教师或家长的电子邮件地址(每个教师和家长也是数据库中的一个文档) 例如,学生文档可能如下所示 { &qu

我决定将couchDB用于我正在进行的一个项目。我正在使用ExpressJS在NodeJS中实现一个服务器,并将其用作我的coach库

我有一个简单的用户数据库,包含不同类型的用户。基本上,我有三种类型的用户:学生、家长和老师。我决定让学生们更容易找到他们父母和老师的推荐信。i、 e数据库中的学生文档可能有两个类型为数组的字段,分别称为
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": "teacher1",
    "age": 38,
    "email": "teacher1@example.com", //this is also part of the _id for this document
    "teacherOf" : ["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"]

}
父文档看起来像

 {
    "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
}
 {
    "name": "parent1",
    "age": 45,
    "email": "parent1@example.com", //this is also part of the _id for this document
    "parentOf" : ["student@example.com"]
}
我正在努力实现的目标

我正在尝试创建一个按电子邮件地址检索用户的视图。此视图查找具有该特定电子邮件地址的用户并返回该文档。如果此用户是教师或家长,我希望查看数据库中的所有文档并搜索潜在的学生家长或学生教师关系。例如,如果我使用是搜索
teacher1@example.com
,我的结果对象应该如下所示

 {
    "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": "teacher1",
    "age": 38,
    "email": "teacher1@example.com", //this is also part of the _id for this document
    "teacherOf" : ["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"]

}
或者如果我正在搜索
parent1@example.com
,结果应该如下所示

 {
    "name": "teacher1",
    "age": 38,
    "email": "teacher1@example.com", //this is also part of the _id for this document
}
 {
    "name": "parent1",
    "age": 45,
    "email": "parent1@example.com", //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, {studentEmail: doc.email, relationship: 'parent'});
        });
     },
    reduce: function(key, values) {
          return values;
     }
此视图称为
all\u details

然后我有一个简单的节点函数,它使用nano来调用这个视图

testFindAllDetails(email) {
        return this._usersDB.view('_users', 'all_details', {
            key: email
        });
    }
例如,当我按当前状态调用此视图时,调用
testFindAllDetails('teacher2@example.com)
,我得到的结果如下

{
    "rows": [
        {
            "key": null,
            "value": [
                [
                    {
                        "name": "teacher2",
                        "age": 52,
                        "email": "teacher2@example.com",
                    }
                ],
                [
                    {
                        "studentEmail": "student@example.com",
                        "relationship": "teacher"
                    },
                    {
                        "studentEmail": "student@example.com",
                        "relationship": "parent"
                    }
                ]
            ]
        }
    ]
}
{
    "total_rows": 20,
    "offset": 2,
    "rows": [
        {
            "id": "org.couchdb.user:teacher2@example.com",
            "key": "teacher2@example.com",
            "value": {
                "name": "teacher2",
                "age": 52,
                "email": "teacher2@example.com"
            }
        },
        {
            "id": "org.couchdb.user:student@example.com",
            "key": "teacher2@example.com",
            "value": {
                "studentEmail": "student@example.com",
                "relationship": "teacher"
            }
        },
        {
            "id": "org.couchdb.user:student@example.com",
            "key": "teacher2@example.com",
            "value": {
                "studentEmail": "student@example.com",
                "relationship": "parent"
            }
        }
    ]
}
我的问题是,如何使用我的
reduce
函数将结果合并到一个对象中?我的
map
正在成功检索所有拥有该电子邮件的学生,即
'teacher2@example.com“
在他们的
家长
教师
字段中,但我不确定如何使用
reduce视图的一部分以将其全部合并到一个对象中

如果我去掉视图的reduce部分并运行相同的函数
testFindAllDetails('teacher2@example.com)
,这就是我的结果

{
    "rows": [
        {
            "key": null,
            "value": [
                [
                    {
                        "name": "teacher2",
                        "age": 52,
                        "email": "teacher2@example.com",
                    }
                ],
                [
                    {
                        "studentEmail": "student@example.com",
                        "relationship": "teacher"
                    },
                    {
                        "studentEmail": "student@example.com",
                        "relationship": "parent"
                    }
                ]
            ]
        }
    ]
}
{
    "total_rows": 20,
    "offset": 2,
    "rows": [
        {
            "id": "org.couchdb.user:teacher2@example.com",
            "key": "teacher2@example.com",
            "value": {
                "name": "teacher2",
                "age": 52,
                "email": "teacher2@example.com"
            }
        },
        {
            "id": "org.couchdb.user:student@example.com",
            "key": "teacher2@example.com",
            "value": {
                "studentEmail": "student@example.com",
                "relationship": "teacher"
            }
        },
        {
            "id": "org.couchdb.user:student@example.com",
            "key": "teacher2@example.com",
            "value": {
                "studentEmail": "student@example.com",
                "relationship": "parent"
            }
        }
    ]
}
总而言之,问题是如何将结果组合成这样的结果

 {
    "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": "teacher1",
    "age": 38,
    "email": "teacher1@example.com", //this is also part of the _id for this document
    "teacherOf" : ["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"]

}
其中创建了两个新字段,
teacherOf
parentOf
,这些字段是由可能与该教师或家长有关系的所有学生组成的数组

顺便说一句,如果使用学生电子邮件调用相同的函数,例如
testFindAllDetails('student@example.com“)
,结果可能包括也可能不包括
teacherOf
parentOf
字段,但如果它确实包括它们,则它们可以是空数组

 {
    "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"],
    "teachers": ["teacher1@example.com", "teacher2@example.com"],
    "parentOf": [],
    "teacherOf": []
}
提前感谢您在这方面的帮助