RethinkDB: RqlRuntimeError: Невозможно выполнить скобки для последовательности последовательностей

Даны следующие документы в таблице:

[
  {
    "id": "d30aa369-99d6-4a40-9547-2cbdf0bb069a",
    "locations": [
      {
        "alerts": [
          {"person": 200},
          {"person": 300}
        ],
        "name": "home"
      },
      {
        "alerts": [
          {"person": 200},
          {"person": 300}
        ],
        "name": "work"
      }
    ],
    "person": 100
  },
  {
    "id": "d671d2c7-0e0d-43c0-9148-9e6b049b49a7",
    "locations": [
      {
        "alerts": [
          {"person": 100},
          {"person": 300}
        ],
        "name": "home"
      },
      {
        "alerts": [
          {"person": 100},
          {"person": 300}
        ],
        "name": "work"
      }
    ],
    "person": 200
  }
] 

Я хочу вернуть все местоположения, в которых есть предупреждение, содержащее конкретного человека. Я думал, что это будет немного примерно так:

r.db('db').table('test')('locations').filter(function(location){
  return location('alerts')('person').eq(200);
});

Все же я получаю:

RqlRuntimeError: Невозможно выполнить скобки для последовательности последовательностей в:

Как правильно выполнить этот запрос?

1 ответ

Решение

Всякий раз, когда вы получаете ошибку "последовательность последовательностей", решение обычно включает использование concatMap.

В этом случае, я думаю, это даст вам то, что вы хотите:

r.db('db').table('table')
    .concatMap(r.row('locations'))
    .filter(r.row('alerts')('person').contains(200))

concatMap с функцией идентичности function(x){return x} также известен как "flatten" (хотя нет термина reql под названием flatten)

Редактировать:

Если вы хотите вернуть весь документ верхнего уровня, вам нужно немного продвинуть concatMap вниз и использовать идиому "flatten", о которой я упоминал выше:

r.db('db').table('table').filter(function(person){
    return person
      ('locations')
      ('alerts')
      .concatMap(function(x){return x}) // flatten
      ('person')
      .contains(200)
})
Другие вопросы по тегам