Запрос ArangoDB для массивов

У меня проблема с запросом ArangoDB в java для значения Arrays. Я пробовал использовать как String [], так и ArrayList, но безуспешно.

Мой запрос:

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

BindParams:

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

categoriesArray содержит набор строк. Я не уверен, почему он не возвращает никаких результатов, потому что, если я запрашиваю, используя:

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

Я получаю результаты, которые ищу. Только не при использовании Array или ArrayList.

Я также попытался запросить:

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

чтобы имитировать ArrayList, но это не возвращает никаких результатов. Я бы запросил несколько отдельных строк, но их слишком много, и я получаю сообщение об ошибке от драйвера Java при запросе с такой длинной строкой. Таким образом, я должен запросить, используя массив или ArrayList.

Пример categoryArray:

["Politics", "Law", "Nature"]

Образец изображения базы данных:

введите описание изображения здесь


person JosephG    schedule 14.01.2015    source источник


Ответы (2)


Причина в том, что оператор 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
person stj    schedule 14.01.2015
comment
Как насчет 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). Как насчет EVERY() и SOME() в AQL? SOME(["Law","Politics"], doc.categories[*].title)) - person CodeManX; 08.08.2015
comment
Я согласен, EVERY и SOME были бы полезны в AQL. Я не уверен, что предоставление их в виде функций обеспечит наиболее интуитивно понятный синтаксис, но, вероятно, будет проще всего. - person stj; 10.08.2015

В Аранго также (сейчас) есть операторы сравнения массивов которые позволяют искать ALL IN, ANY IN или NONE 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
person Jordan Whitfield    schedule 17.03.2020