Hi,
I’m trying to implement a user list with followers in n1ql. I already have it working with views, but trying to see if I can get better performance with n1ql.
Desired output:
user A: 3
user B: 5
user C: 10
Current document structure
{
"entityType": "activity",
"target": "user",
"target_id": "a user id here"
"action": "follow"
}
Index
create index idx_activity_follow on mybucket (entityType, target, target_id, action);
Getting # of followers for a single user works fine. It takes under 10ms.
select count(target_id) from mybucket where entityType='activity' and target='user' and action='follow' and target_id='user_id'
But getting # of followers for multiple users takes long time. It takes over a minute and eventually displays index scan time out.
select count(target_id) from mybucket where entityType='activity' and target='user' and action='follow' and target_id in ['user_id', 'user_id2']
Explain
{
"requestID": "c802177d-235b-475e-b8bf-27280a64a56c",
"signature": "json",
"results": [
{
"plan": {
"#operator": "Sequence",
"~children": [
{
"#operator": "IndexScan",
"covers": [
"cover ((`mybucket`.`entityType`))",
"cover ((`mybucket`.`target`))",
"cover ((`mybucket`.`target_id`))",
"cover ((`mybucket`.`action`))",
"cover ((meta(`mybucket`).`id`))"
],
"index": "idx_activity_follow",
"index_id": "e88a694859a8a70a",
"keyspace": "mybucket",
"namespace": "default",
"spans": [
{
"Range": {
"High": [
"successor(\"activity\")"
],
"Inclusion": 1,
"Low": [
"\"activity\""
]
}
}
],
"using": "gsi"
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "Filter",
"condition": "((((cover ((`mybucket`.`entityType`)) = \"activity\") and (cover ((`mybucket`.`target`)) = \"user\")) and (cover ((`mybucket`.`action`)) = \"follow\")) and (cover ((`mybucket`.`target_id`)) in [\"kakin\"]))"
},
{
"#operator": "InitialGroup",
"aggregates": [
"count(cover ((`mybucket`.`target_id`)))"
],
"group_keys": []
}
]
}
},
{
"#operator": "IntermediateGroup",
"aggregates": [
"count(cover ((`mybucket`.`target_id`)))"
],
"group_keys": []
},
{
"#operator": "FinalGroup",
"aggregates": [
"count(cover ((`mybucket`.`target_id`)))"
],
"group_keys": []
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "InitialProject",
"result_terms": [
{
"expr": "count(cover ((`mybucket`.`target_id`)))"
}
]
},
{
"#operator": "FinalProject"
}
]
}
}
]
},
"text": "select count(target_id) from mybucket where entityType='activity' and target='user' and action='follow' and target_id in ['kakin']"
}
],
"status": "success",
"metrics": {
"elapsedTime": "4.180504ms",
"executionTime": "4.143132ms",
"resultCount": 1,
"resultSize": 3935
}
}
Is there a way to improve it?