我想查询(或索引)一个数组值的字段。
例如,假设我要检索此文档{ "myarray": [ 1, 2, 3]}
。
我可以做到这一点
ANY...SATISFIES
或使用UNNEST
。从documentation来看,这些功能在功能上是相同的。
SELECT * FROM `bucket` AND ANY v in myarray SATISFIES v=3 END;
SELECT * FROM `bucket` UNNEST myarray v WHERE v=3
每种情况都有哪些用例?
答案 0 :(得分:2)
对于这两个查询,它们执行相似的操作,但是这两种方法都提供了其他功能。
这两个查询的实际结果应该不同。第一个查询将按原样返回数组数据,而UNNEST将平整数组。
UNNEST是文档内联接。 SATISFIES允许您(完成操作)检查数组以查看其是否符合某些条件,但实际上并不会以任何方式转换数组的结果。
更新:
不一定是“哪个更好”的问题。这两个查询都做不同的事情。假设您的文档如下所示:
{
"foo": "bar",
"myarray": [
1,
2,
3
]
}
现在假设您从这两个查询中都删除了WHERE
。
然后,运行此查询:
SELECT d.foo, d.myarray, v
FROM `demo` d
UNNEST d.myarray v
您将获得3个结果,因为正在进行联接。像这样:
[
{"foo":"bar","myarray":[1,2,3],"v":1},
{"foo":"bar","myarray":[1,2,3],"v":2},
{"foo":"bar","myarray":[1,2,3],"v":3}
]
对于其他查询:
SELECT d.*
FROM `demo` d
您将获得一个结果,因为没有加入发生。这是文档内谓词,但不是文档内联接。
[{"foo":"bar","myarray":[1,2,3]}]
要使用哪个?一般来说,这取决于您的用例。堆栈溢出不是用于提供此类特定于激光器的建议。如果您只是追求速度,我建议对您的真实数据进行测试,以查看哪种效率更高(您的样本文档可能不是您的真实文档)。
Indexing is also a factor。同样,仅基于示例文档,对于SATISFIES查询,您可能会创建一个如下所示的索引:
CREATE INDEX adv_DISTINCT_myarray ON `demo`(DISTINCT `myarray`)
对于UNNEST查询,您可能会创建一个像这样的索引:
CREATE INDEX adv_ALL_myarray ON `demo`(ALL `myarray`)
这些索引假定您要做的只是检查myarray
中的单个值。如果您的实际查询更复杂,那么您将需要一个更复杂的索引。
另外一个注意事项:在幕后,在查询引擎中,我不知道实现的区别是什么,因此我不得不接受Johan的建议,即UNNEST的价格更高。但是您的里程可能会有所不同,所以我建议您同时尝试并做一些基准测试。
答案 1 :(得分:2)
第一个是内部文档谓词,查询结果是来自“存储桶”的文档。第二个查询将“ bucket”中的每个文档与“ myarray”中的值进行联接,并且查询的每个结果都是“ bucket”中的文档副本和“ myarray”中的一个值。
通常来说,期望第二种选择更加昂贵。