在检查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
属性 类型为 object
或 message
属性 为字符串并匹配特定正则表达式的文档 (使用 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'))
)
})
此查询将return你们所有在table消息上注册的具有字段message且该字段为String的消息。
干杯。
r.db('test').table('message').hasFields('message')
.filter(function (row) {
return row('message').typeOf().eq('STRING')
})
我在 rethinkdb 中几乎没有包含各种数据集的表。主要是因为随着时间的推移,从简单的字符串属性中创建了复杂的对象以使其更具表现力。
当我 运行 查询时,我要确保所有字段都存在,并且 hasFields - function。但是,如果我想 运行 在我的 Message
属性 上进行 RegExp 查询,它可以是字符串或对象类型。当然,如果它是一个对象,我不关心行,但是 rethinkdb 没有忽略它,而是抛出错误:
Unhandled rejection RqlRuntimeError: Expected type STRING but found OBJECT in...
我能否以某种方式使用 typeOf 在 运行 查询之前首先确定类型?
或者这样做的好方法是什么?
我不是 100% 清楚你的问题,所以我将重述问题以确保我的解决方案有意义。
问题
获取所有 message
属性 类型为 object
或 message
属性 为字符串并匹配特定正则表达式的文档 (使用 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'))
)
})
此查询将return你们所有在table消息上注册的具有字段message且该字段为String的消息。 干杯。
r.db('test').table('message').hasFields('message')
.filter(function (row) {
return row('message').typeOf().eq('STRING')
})