rethinkdb / rethinkdb-ts

RethinkDB TypeScript driver
Apache License 2.0
123 stars 17 forks source link

ReqlUnknownError: Cannot use r.row in nested queries. #40

Closed BannerBomb closed 2 years ago

BannerBomb commented 4 years ago

Doing something like this

const { r } = require('rethinkdb-ts');
await r.db('stratobotelite').table('guilds').filter(r.row('roboboard').hasFields('messages')).update({ roboboard: r.literal({ messages: r.row('roboboard').getField('messages').filter(r.js("(function(val) { return val > ((Date.now() - 1421280000000) * 4194304) })")) }) }, { nonAtomic: true }).run()

using this package seems to give me the error

ReqlUnknownError: Cannot use r.row in nested queries.  Use functions instead in:
r.db("stratobotelite").table("guilds").filter(r.row("roboboard").hasFields("messages"))
    .update({
        roboboard: r.literal({
            messages: r.row("roboboard").getField("messages").filter(r.js("(function(val) {
                      ^^^^^                                                                
                return val > ((Date.now() - 1421280000000) * 4194304)
            })"))
        })
    }, {
        nonAtomic: true
    })

    at Cursor.handleErrors (/opt/stratobotelite/node_modules/rethinkdb-ts/lib/response/cursor.js:248:23)
    at Cursor.resolve (/opt/stratobotelite/node_modules/rethinkdb-ts/lib/response/cursor.js:185:18)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Proxy.<anonymous> (/opt/stratobotelite/node_modules/rethinkdb-ts/lib/query-builder/term-builder.js:79:29)
    at async eval (eval at eval (/opt/stratobotelite/src/commands/Admin/eval.js:109:13), <anonymous>:3:9)
    at async module.exports.eval (/opt/stratobotelite/src/commands/Admin/eval.js:115:14)
    at async module.exports.run (/opt/stratobotelite/src/commands/Admin/eval.js:23:43)
    at async module.exports.runCommand (/opt/stratobotelite/src/monitors/commandHandler.js:59:23)
    at async module.exports._run (/opt/stratobotelite/node_modules/klasa/src/lib/structures/Monitor.js:99:4)

but running the exact same script with the dataexplorer works perfectly fine :thinking: image

atassis commented 4 years ago

@BannerBomb You should use functional query like .filter(i => ({ roboboard: i('something') })). rethinkdb doen't have the scope in r execution, thats why you need to directly declare a variable to be used.

NetOpWibby commented 2 years ago

I just ran into this issue as well.

const allDocuments = await r.table(tableName)
  .filter(
    // THIS SHOULD WORK B/C THE DATA EXPLORER HAS NO PROBLEM WITH IT
    // ERROR: Cannot use r.row in nested queries. Use functions instead
    r.row("name").match(`^${query.startsWith}`).and(r.row("tier").eq(query.tier))
  )
  .orderBy(r.asc("created"))
  .limit(limit)
  .run(databaseConnection);

Interestingly, trying out your solution gave the same error:

.filter(_ => ({
  name: r.row("name").match(`^${query.startsWith}`),
  tier: r.row("tier").eq(query.tier)
}))
atassis commented 2 years ago

Thats totally not what I have suggested. I have advised to use the i argument, though you just skip it and continue using the r

.filter(i => ({
  name: i("name").match(`^${query.startsWith}`),
  tier: i("tier").eq(query.tier)
}))
atassis commented 2 years ago

About an error itself- it will take a time to turn out why it is handled as an error. I am not quite good at understanding how to resolve it, but that's an issue so I'll mention it while continue researching the code. So for now you can use the solution above, I don't see any potential issues for you.

NetOpWibby commented 2 years ago

Ah, thanks for the corrected code. I no longer get an issue but I also don't get any documents returned.

NetOpWibby commented 2 years ago

I was looking through the code and I have no idea what to look for either. I'll keep looking as well though.

NetOpWibby commented 2 years ago

When I throw i into a console.log I get a bunch of functions that are exposed by r, I believe:

[Function] {
  term: [ 10, [ 1 ] ],
  toString: [Function],
  run: [AsyncFunction],
  getCursor: [AsyncFunction],
  do: [Function],
  table: [Function],
  get: [Function],
  getAll: [Function],
  eq: [Function],
  ne: [Function],
  lt: [Function],
  le: [Function],
  gt: [Function],
  ge: [Function],
  not: [Function],
  add: [Function],
  sub: [Function],
  mul: [Function],
  div: [Function],
  mod: [Function],
  floor: [Function],
  ceil: [Function],
  round: [Function],
  append: [Function],
  prepend: [Function],
  difference: [Function],
  setInsert: [Function],
  setIntersection: [Function],
  setUnion: [Function],
  setDifference: [Function],
  slice: [Function],
  skip: [Function],
  limit: [Function],
  offsetsOf: [Function],
  contains: [Function],
  getField: [Function],
  keys: [Function],
  values: [Function],
  hasFields: [Function],
  withFields: [Function],
  pluck: [Function],
  without: [Function],
  merge: [Function],
  between: [Function],
  reduce: [Function],
  map: [Function],
  fold: [Function],
  filter: [Function],
  concatMap: [Function],
  orderBy: [Function],
  distinct: [Function],
  count: [Function],
  isEmpty: [Function],
  union: [Function],
  nth: [Function],
  innerJoin: [Function],
  outerJoin: [Function],
  eqJoin: [Function],
  zip: [Function],
  insertAt: [Function],
  deleteAt: [Function],
  changeAt: [Function],
  spliceAt: [Function],
  coerceTo: [Function],
  typeOf: [Function],
  update: [Function],
  delete: [Function],
  replace: [Function],
  insert: [Function],
  tableCreate: [Function],
  tableDrop: [Function],
  tableList: [Function],
  config: [Function],
  status: [Function],
  wait: [Function],
  reconfigure: [Function],
  rebalance: [Function],
  sync: [Function],
  grant: [Function],
  indexCreate: [Function],
  indexDrop: [Function],
  indexList: [Function],
  indexStatus: [Function],
  indexWait: [Function],
  indexRename: [Function],
  branch: [Function],
  or: [Function],
  and: [Function],
  forEach: [Function],
  info: [Function],
  match: [Function],
  upcase: [Function],
  downcase: [Function],
  sample: [Function],
  default: [Function],
  toISO8601: [Function],
  toEpochTime: [Function],
  inTimezone: [Function],
  during: [Function],
  date: [Function],
  timeOfDay: [Function],
  timezone: [Function],
  year: [Function],
  month: [Function],
  day: [Function],
  dayOfWeek: [Function],
  dayOfYear: [Function],
  hours: [Function],
  minutes: [Function],
  seconds: [Function],
  group: [Function],
  sum: [Function],
  avg: [Function],
  min: [Function],
  max: [Function],
  split: [Function],
  ungroup: [Function],
  changes: [Function],
  toGeojson: [Function],
  distance: [Function],
  intersects: [Function],
  includes: [Function],
  getIntersecting: [Function],
  fill: [Function],
  getNearest: [Function],
  polygonSub: [Function],
  toJSON: [Function],
  toJsonString: [Function],
  setWriteHook: [Function],
  getWriteHook: [Function],
  bitAnd: [Function],
  bitOr: [Function],
  bitXor: [Function],
  bitNot: [Function],
  bitSal: [Function],
  bitShl: [Function],
  bitSar: [Function],
  bitShr: [Function],
  [Symbol(RethinkDBQuery)]: true
}

EDIT: It's the same as exposing the document in the filter function actually.

atassis commented 2 years ago

This is just a query builder object instance; you won't receive a document that way. Any console.logs server side are not sent to the rethinkdb, executed and returned back, it's not working that way. All you do with r.[command] stuff is you generate a query, which is sent server side and then wait for data being return. So you might have an issue with the conditions you provide

NetOpWibby commented 2 years ago

I'm just passing plain strings, idk what's going on.

atassis commented 2 years ago

This is quite not related to a current issue, I think it'ld be easier if you ask it in the help channel in clack

NetOpWibby commented 2 years ago

I did that first actually, before coming here. I'll just close this. Finally looking into Postgres instead.