I am using Couchbase Server Version: 4.5.0-2203 Enterprise Edition (build-2203) (4.5Beta)
any my sample document looks like the following:
{"id":"R::1","type":"relationship","owner_members":["user1"],"normal_members":["user2","user3"],"guest_members":["user4"]}
{"id":"R::2","type":"relationship","owner_members":["user1","user2"],"normal_members":["user4"],"guest_members":[]}
{"id":"R::3","type":"relationship","owner_members":["user4"],"normal_members":["user1"],"guest_members":["user3"]}
I want to get those documents where user belongs to any members of owner_members/normal_members/guest_members
for example, for user2
as query condition, I can get R::1
and R::2
documents info.
So I want to try to use array index here, I create the following index:
CREATE PRIMARY INDEX `pidx-mydb` ON `mydb` USING GSI;
CREATE INDEX `idx-type` ON `mydb`(type) USING GSI;
CREATE INDEX `idx-rel_owner_members` ON `mydb`(DISTINCT ARRAY o FOR o IN owner_members END) WHERE (type = "relationship");
CREATE INDEX `idx-rel_normal_members` ON `mydb`(DISTINCT ARRAY n FOR n IN normal_members END) WHERE (type = "relationship");
CREATE INDEX `idx-rel_guest_members` ON `mydb`(DISTINCT ARRAY g FOR g IN guest_members END) WHERE (type = "relationship");
My N1QL looks like this:
select meta(a).id,a.owner_members,a.normal_members,a.guest_members
from mydb as a
where
(a.type == "relationship" AND ANY AND EVERY o IN a.owner_members SATISFIES o == "user2" END)
OR
(a.type == "relationship" AND ANY AND EVERY n IN a.normal_members SATISFIES n == "user2" END)
OR
(a.type == "relationship" AND ANY AND EVERY g IN a.guest_members SATISFIES g == "user2" END)
;
but EXPLAIN
shows only idx-type be used. Following is the result of EXPLAIN:
[
{
"plan": {
"#operator": "Sequence",
"~children": [
{
"#operator": "DistinctScan",
"scan": {
"#operator": "IndexScan",
"index": "idx-type",
"index_id": "42c69e2edecf0e60",
"keyspace": "mydb",
"namespace": "default",
"spans": [
{
"Range": {
"High": [
"\"relationship\""
],
"Inclusion": 12,
"Low": [
"\"relationship\""
]
}
},
{
"Range": {
"High": [
"\"relationship\""
],
"Inclusion": 12,
"Low": [
"\"relationship\""
]
}
},
{
"Range": {
"High": [
"\"relationship\""
],
"Inclusion": 12,
"Low": [
"\"relationship\""
]
}
}
],
"using": "gsi"
}
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "Fetch",
"as": "a",
"keyspace": "mydb",
"namespace": "default"
},
{
"#operator": "Filter",
"condition": "(((((`a`.`type`) = \"relationship\") and any and every `o` in (`a`.`owner_members`) satisfies (`o` = \"user2\") end) or (((`a`.`type`) = \"relationship\") and any and every `n` in (`a`.`normal_members`) satisfies (`n` = \"user2\") end)) or (((`a`.`type`) = \"relationship\") and any and every `g` in (`a`.`guest_members`) satisfies (`g` = \"user2\") end))"
},
{
"#operator": "InitialProject",
"result_terms": [
{
"expr": "(meta(`a`).`id`)"
},
{
"expr": "(`a`.`owner_members`)"
},
{
"expr": "(`a`.`normal_members`)"
},
{
"expr": "(`a`.`guest_members`)"
}
]
},
{
"#operator": "FinalProject"
}
]
}
}
]
},
"text": "select meta(a).id,a.owner_members,a.normal_members,a.guest_members\nfrom mydb as a \nwhere \n(a.type == \"relationship\" AND ANY AND EVERY o IN a.owner_members SATISFIES o == \"user2\" END)\nOR\n(a.type == \"relationship\" AND ANY AND EVERY n IN a.normal_members SATISFIES n == \"user2\" END)\nOR\n(a.type == \"relationship\" AND ANY AND EVERY g IN a.guest_members SATISFIES g == \"user2\" END)\n;"
}
]
Is there any way to improve performance by using array index like this?