I am using PouchDB and I have a dataset representing a social network in a graph. People are documents, and the people they follow are in an array of the _id
of the person followed. Here is a sample of the data:
[
{
"_id": "mc0001",
"name": "Jill Martin",
"joined": "2020-01-15",
"follows": []
},
{
"_id": "mc0002",
"name": "Elena Markova",
"joined": "2020-01-21",
"follows": ["mc0001"]
},
{
"_id": "mc0003",
"name": "Carlos Sanchez",
"joined": "2020-01-27",
"follows": ["mc0001", "mc0002"]
},
{
"_id": "mc0004",
"name": "Ai Sato",
"joined": "2020-02-21",
"follows": ["mc0001", "mc0003"]
},
{
"_id": "mc0005",
"name": "Ming Wu",
"joined": "2020-03-21",
"follows": ["mc0002", "mc0003", "mc0004"]
}
]
What I would like to do is query for each person, and get a list of followers. I am looking for something like this:
[
{
"_id": "mc0001",
"followers": ["mc0002", "mc0003", "mc0004"]
},
{
"_id": "mc0002",
"followers": ["mc0003", "mc0005"]
},
{
"_id": "mc0003",
"followers": ["mc0004", "mc0005"]
},
{
"_id": "mc0004",
"followers": ["mc0005"]
},
{
"_id": "mc0005",
"followers": []
}
]
Is there a way to do this without changing the data structure (e.g. moving the followers array into the doc of the person being followed)?
Create a Map/Reduce view that loops through the follows
array in each document and emits those; like this:
function (doc) {
for(var i =0; i<doc.follows.length; i++) {
emit(doc.follows[i], null);
}
}
You end up with an index keyed on a user and where each row has the id of a follower of that user. You can then query the index, supplying the key of the user whose followers you want to find, like this:
$URL/users/_design/users/_view/by-follower?key="mc0001"&reduce=false
You will get something like this:
{"total_rows":8,"offset":0,"rows":[
{"id":"mc0002","key":"mc0001","value":null},
{"id":"mc0003","key":"mc0001","value":null},
{"id":"mc0004","key":"mc0001","value":null}
]}
This is not exactly the format of the data you have in your question, but you can see that the id
field in each object contains a follower of your desired user, so you can go from there.