在检查rethinkdb中的值之前如何检查字段的类型?

How to check the type of a field before checking the value in rethinkdb?

我在 rethinkdb 中几乎没有包含各种数据集的表。主要是因为随着时间的推移,从简单的字符串属性中创建了复杂的对象以使其更具表现力。

当我 运行 查询时,我要确保所有字段都存在,并且 hasFields - function。但是,如果我想 运行 在我的 Message 属性 上进行 RegExp 查询,它可以是字符串或对象类型。当然,如果它是一个对象,我不关心行,但是 rethinkdb 没有忽略它,而是抛出错误:

Unhandled rejection RqlRuntimeError: Expected type STRING but found OBJECT in...

我能否以某种方式使用 typeOf 在 运行 查询之前首先确定类型?

或者这样做的好方法是什么?

我不是 100% 清楚你的问题,所以我将重述问题以确保我的解决方案有意义。

问题

获取所有 message 属性 类型为 objectmessage 属性 为字符串并匹配特定正则表达式的文档 (使用 match 方法)。

解决方案

您基本上需要一个 if 语句。为此,您可以根据这些条件使用 r.branch 到 'branch' 您的条件。

这是一个很长但很清楚的例子,说明如何做到这一点:

假设您有这些文档,并且您想要 message 属性 是对象或包含子字符串 'string' 的字符串的所有文档。文档如下所示:

{
  "id":  "a1a17705-e7b0-4c84-b9d5-8a51f4599eeb" ,
  "message":  "invalid"
}, {
  "id":  "efa3e26f-2083-4066-93ac-227697476f75" ,
  "message":  "this is a string"
}, {
 "id":  "80f55c96-1960-4c38-9810-a76aef60d678" ,
  "not_messages": "hello"
}, {
  "id":  "d59d4e9b-f1dd-4d23-a3ef-f984c2361226" ,
  "message": {
    "exists": true ,
    "text":  "this is a string"
  }
}

为此,您可以使用以下查询:

r.table('messages')
  .hasFields('message') // only get document with the `message` property
  .filter(function (row) { 
    return r.branch( // Check if it's an object
      row('message').typeOf().eq('OBJECT'), // return true if it's an object
      true,
      r.branch( // Check if it's a string
        row('message').typeOf().eq('STRING'),
        r.branch( // Only return true if the `message` property ...
          row('message').match('string'), // has the substring `string`
          true,
          false // return `false` if it's a string but doesn't match our regex
        ),
        false // return `false` if it's neither a string or an object
      )
    )
  })

同样,这个查询很长,可以写得更优雅,但它非常清楚地解释了 branch 的用法。

编写此查询的更短方式是:

r.table('messages')
  .hasFields('message')
  .filter(function (row) {
    return 
      row('message').typeOf().eq('OBJECT')
        .or(
          row('message').typeOf().eq('STRING').and(row('message').match('string'))
        )
  })

这基本上使用 and and or 方法而不是 branch

此查询将return你们所有在table消息上注册的具有字段message且该字段为String的消息。 干杯。

r.db('test').table('message').hasFields('message')
.filter(function (row) { 
    return row('message').typeOf().eq('STRING')
})