N1QL查询:如何获取ID不在Playlist文档tracksId数组中的所有Track记录
解决N1QL查询中NOT IN匹配数组字段的问题
嘿,这个问题我之前也踩过坑!你写的子查询返回的其实是包含tracksId数组的文档对象(比如[{"tracksId": [1,2]}]),而NOT IN需要的是单个ID的集合,所以才会失效。下面给你几个靠谱的解决思路:
方法一:用UNNEST展开数组(最推荐)
在子查询里通过UNNEST把tracksId数组拆成单个ID元素,这样子查询返回的就是纯ID集合,NOT IN就能正常工作了:
SELECT * FROM Track WHERE id NOT IN ( SELECT tId FROM Playlist WHERE id = 1 -- 如果id是文档主键,换成USE KEYS "1"会更高效 UNNEST tracksId AS tId )
要是你的Playlist文档主键就是id字段,用USE KEYS "1"替代WHERE id = 1能大幅提升查询性能,因为直接走主键索引了。
方法二:用ARRAY_CONTAINS直接判断
换个思路,不用子查询返回集合,而是直接关联Playlist文档,用ARRAY_CONTAINS函数判断Track的id是否不在目标数组里:
SELECT t.* FROM Track t JOIN Playlist p ON p.id = 1 WHERE NOT ARRAY_CONTAINS(p.tracksId, t.id)
这种写法更直观,逻辑清晰,小数据集下性能表现也很好。
方法三:提取子查询的数组值
如果一定要保留子查询的结构,可以用RAW关键字让子查询只返回数组本身,再取第一个结果(因为你只查id=1的Playlist,结果只有一个):
SELECT * FROM Track WHERE id NOT IN ( SELECT RAW p.tracksId FROM Playlist p WHERE p.id = 1 )[0]
这里的RAW会让子查询返回[[1,2]],然后[0]取出里面的[1,2]数组,这样NOT IN就能匹配数组里的每个元素了。
补充:原查询失效的原因
原查询SELECT tracksId FROM Playlist WHERE id = 1返回的是[{"tracksId": [1,2]}]——一个包含对象的数组,而NOT IN需要的是类似[1,2]这样的单个值集合,自然没法匹配。上面的方法都是把这个嵌套结构转换成NOT IN能识别的格式~
内容的提问来源于stack exchange,提问作者michielenzo
相关产品推荐
相关产品推荐

