我尝试在联接的右侧部分进行过滤时执行LEFT OUTER JOIN
。
我创建了以下索引来实现此目的:
CREATE INDEX `idx_store_order` ON `myBucket`(("Store::" || `storeId`)) WHERE ((`docType` = "Order") or (`docType` is missing))
我试图执行以下查询:
SELECT store.status, order.clientId, store.docId
FROM myBucket store
LEFT OUTER JOIN myBucket order ON KEY ("Store::" || order.storeId) FOR store
WHERE store.docType="Store"
AND (order.docType="Order" OR order.docType IS MISSING)
AND order.clientId="9281ae36-a418-4ea3-93f0-bfd7b1a38248"
我有30个带docType="Store"
的文档,但是当我执行此查询时,我没有得到30个结果。如果我删除最后一个子句并逐个存储,那么我得到30个结果,所以这是影响最终结果的最后一个子句。
我还尝试了以下语句(不成功)作为最后一句:
(AND order.clientId="9281ae36-a418-4ea3-93f0-bfd7b1a38248" OR order.docType IS MISSING)
我错过了什么吗?感谢
修改 这是解释查询:
[
{
"plan": {
"#operator": "Sequence",
"~children": [
{
"#operator": "IndexScan",
"index": "idx_docType",
"index_id": "e498d0c0ee2f0d9d",
"keyspace": "myBucket",
"namespace": "default",
"spans": [
{
"Range": {
"High": [
"\"Store\""
],
"Inclusion": 3,
"Low": [
"\"Store\""
]
}
}
],
"using": "gsi"
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "Fetch",
"as": "store",
"keyspace": "myBucket",
"namespace": "default"
},
{
"#operator": "IndexJoin",
"as": "order",
"for": "store",
"keyspace": "myBucket",
"namespace": "default",
"on_key": "(\"Store::\" || (`order`.`storeId`))",
"outer": true,
"scan": {
"index": "idx_store_order",
"index_id": "a97fce5158e6e573",
"using": "gsi"
}
},
{
"#operator": "Filter",
"condition": "((((`store`.`docType`) = \"Store\") and (((`order`.`docType`) = \"Order\") or ((`order`.`docType`) is missing))) and (((`order`.`clientId`) = \"9281ae36-a418-4ea3-93f0-bfd7b1a138248\") or (`order` is missing)))"
},
{
"#operator": "InitialProject",
"result_terms": [
{
"expr": "(`store`.`status`)"
}
]
},
{
"#operator": "FinalProject"
}
]
}
}
]
},
"text": "SELECT store.status\nFROM myBucket store\nLEFT OUTER JOIN myBucket order ON KEY (\"Store::\" || order.storeId) FOR store\nWHERE store.docType=\"Store\"\nAND (order.docType=\"Order\" OR order.docType IS MISSING)\nAND (order.clientId=\"9281ae36-a418-4ea3-93f0-bfd7b1a138248\" OR order IS MISSING)"
}
]
EDIT2
正如评论中所讨论的,我想列出所有商店,无论给定客户是否有订单。如果客户确实有订单,那么我想显示某些字段以及商店列表。
E.g。 商店1 - 客户X没有订单 商店2 - 客户X确实有一个订单,并且商店信息中显示了一些信息
答案 0 :(得分:1)
外连接产生所有左侧文档,而不管是否成功匹配连接键谓词(而不是where子句中的任何条件)。这意味着,无论您是否匹配order.storeId,都可获得30个结果。
在这种情况下,最后一个过滤器是在客户端ID上,它在JOIN之后应用,因此正在过滤一些文档。检查/发布EXPLAIN输出以进行验证。
答案 1 :(得分:0)
在当前的N1QL中,WHERE子句不被视为JOIN谓词的一部分,因此您必须执行以下操作。您需要始终逃避订单,或使用其他别名。
SELECT store.status, order.userId, store.docId
FROM myBucket store
LEFT OUTER JOIN myBucket order ON KEY ("Store::" || order.storeId) FOR store
WHERE store.docType="Store"
AND (
(order IS MISSING)
OR
((order.docType="Order" OR order.docType IS MISSING)
AND order.clientId="9281ae36-a418-4ea3-93f0-bfd7b1a38248")