查询 ArangoDB 中的数组

8

我希望你能帮我翻译一下在Java中查询ArangoDB数组值的问题。我尝试过使用String []和ArrayList,但都没有成功。

我的查询语句:

FOR document IN documents FILTER @categoriesArray IN document.categories[*].title RETURN document

绑定参数:

Map<String, Object> bindVars = new MapBuilder().put("categoriesArray", categoriesArray).get();

categoriesArray 包含一组字符串。我不确定为什么它没有返回任何结果,因为如果我使用以下查询:

FOR document IN documents FILTER "Politics" IN document.categories[*].title RETURN document

我能够得到我想要的结果,但是当使用数组或ArrayList时却得不到。

我也尝试查询:

FOR document IN documents FILTER ["Politics","Law] IN document.categories[*].title RETURN document

为了模拟一个ArrayList,但是这并没有返回任何结果。我会使用一堆单独的字符串进行查询,但是数量太多,当使用长度很长的字符串进行查询时,Java驱动程序会出现错误。因此,我必须使用数组或ArrayList进行查询。
categoriesArray的示例:
["Politics", "Law", "Nature"]

一个数据库的示例图像:

在此输入图片描述

2个回答

11

原因是IN运算符通过在右侧数组的每个成员中搜索左侧值来工作。

使用以下查询,如果"Politics"是document.categories[*].title的成员,则会起作用:

FOR document IN documents FILTER "Politics" IN document.categories[*].title RETURN document

即使"Politics"是document.categories[*].title的成员,以下查询也不起作用:

FOR document IN documents FILTER [ "Politics", "Law" ] IN document.categories[*].title RETURN document

这是因为它将在右侧的每个成员中搜索确切的值[ "Politics", "Law" ],而这个值不会存在。你可能要寻找的是一种分别查找"Politics""Law"的比较方法,例如:

FOR document IN documents 
LET contained = (
  FOR title IN [ "Politics", "Law" ]   /* or @categoriesArray */
    FILTER title IN document.categories[*].title 
    RETURN title
)
FILTER LENGTH(contained) > 0
RETURN document

LET categories = ["Politics", "Law"], LET cat_length = LENGTH(categories) & FILTER cat_length == LENGTH(INTERSECTION(categories, document.categories[*].title)),代码看起来更简洁,但不知道性能和内存消耗如何。或者在AQL中是否可能添加对集合的支持?比如 FILTER SET(["Politics", "Law"]) IN SET(document.categories[*].title)。或者在JS中,可以这样做:let arr = ["Law", "Science", "Politics"]; ["Politics","Law"].every(elem => arr.indexOf(elem) != -1)。AQL中的EVERY()SOME()怎么样?例如:SOME(["Law","Politics"], doc.categories[*].title)) - CodeManX
我同意,在AQL中使用EVERYSOME会很有用。我不确定将它们提供为函数是否会提供最直观的语法,但这可能是最简单的方法。 - stj

3

现在,Arango 还具有数组比较运算符,可实现搜索 ALL INANY INNONE IN

[ 1, 2, 3 ]  ALL IN  [ 2, 3, 4 ]  // false
[ 1, 2, 3 ]  ALL IN  [ 1, 2, 3 ]  // true
[ 1, 2, 3 ]  NONE IN  [ 3 ]       // false
[ 1, 2, 3 ]  NONE IN  [ 23, 42 ]  // true
[ 1, 2, 3 ]  ANY IN  [ 4, 5, 6 ]  // false
[ 1, 2, 3 ]  ANY IN  [ 1, 42 ]    // true
[ 1, 2, 3 ]  ANY ==  2            // true
[ 1, 2, 3 ]  ANY ==  4            // false
[ 1, 2, 3 ]  ANY >  0             // true
[ 1, 2, 3 ]  ANY <=  1            // true
[ 1, 2, 3 ]  NONE <  99           // false
[ 1, 2, 3 ]  NONE >  10           // true
[ 1, 2, 3 ]  ALL >  2             // false
[ 1, 2, 3 ]  ALL >  0             // true
[ 1, 2, 3 ]  ALL >=  3            // false
["foo", "bar"]  ALL !=  "moo"     // true
["foo", "bar"]  NONE ==  "bar"    // false
["foo", "bar"]  ANY ==  "foo"     // true

现在您可以通过以下方式进行筛选:

FOR document IN documents 
    FILTER ["Politics", "Law] ANY IN (document.categories[*].title)[**]
    RETURN document

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接