书架:查询生成器:如何对 json 列使用 like 运算符?
Bookshelf: query builder: how to use like operator with json column?
我正在使用 bookshelf 和 postgresql 数据库
信息是 json.
类型的列
我想检索所有类似于“%pattern%”的列
对于 sql 查询,我使用
select * from table where information::text like '%pattern%';
我想用书架查询生成器来做到这一点
model.query(function(qb) {
qb.where('information', 'LIKE', '%pattern%')
}).fetch()
但它没有用,我在 bookshelf docs
中找不到如何做
有什么想法吗?
这里棘手的部分是,虽然您可能认为 JSON(和 JSONB)列是文本,但它们不是!所以没有办法对一个进行 LIKE
比较。嗯,有,但你必须先将它转换为字符串:
SELECT * FROM wombats WHERE information #>> '{}' LIKE '%pattern%';
这是一个非常糟糕的想法,请不要那样做!正如 @GMB 在评论中指出的那样,JSON 是一种功能更强大的结构化格式。 Postgres 擅长处理 JSON,所以只要向它询问你需要什么。假设您的值在名为 description
:
的 JSON 属性 中
SELECT * FROM wombats
WHERE (information->'description')::TEXT
LIKE '%pattern%';
在这里,即使我们已经在 JSON 对象中识别出正确的 属性,它的输出类型为 JSON
:我们仍然必须将其转换为 ::TEXT
,然后使用 LIKE
将其与字符串进行比较。所有这些的 Bookshelf/Knex 版本看起来像:
model
.query(function(qb) {
const keyword = "pattern";
qb.whereRaw(`(information->'description')::TEXT LIKE '%${keyword}%'`)
})
.fetch();
显然这部分原始查询不能参数化(至少在 Postgres 中)所以需要 JavaScript 中的字符串替换。这意味着您应该格外小心该字符串的来源(即仅使用有限的子集,或在使用前进行清理),因为您正在绕过 Knex 的常规保护。
我正在使用 bookshelf 和 postgresql 数据库
信息是 json.
类型的列我想检索所有类似于“%pattern%”的列 对于 sql 查询,我使用
select * from table where information::text like '%pattern%';
我想用书架查询生成器来做到这一点
model.query(function(qb) {
qb.where('information', 'LIKE', '%pattern%')
}).fetch()
但它没有用,我在 bookshelf docs
中找不到如何做有什么想法吗?
这里棘手的部分是,虽然您可能认为 JSON(和 JSONB)列是文本,但它们不是!所以没有办法对一个进行 LIKE
比较。嗯,有,但你必须先将它转换为字符串:
SELECT * FROM wombats WHERE information #>> '{}' LIKE '%pattern%';
这是一个非常糟糕的想法,请不要那样做!正如 @GMB 在评论中指出的那样,JSON 是一种功能更强大的结构化格式。 Postgres 擅长处理 JSON,所以只要向它询问你需要什么。假设您的值在名为 description
:
SELECT * FROM wombats
WHERE (information->'description')::TEXT
LIKE '%pattern%';
在这里,即使我们已经在 JSON 对象中识别出正确的 属性,它的输出类型为 JSON
:我们仍然必须将其转换为 ::TEXT
,然后使用 LIKE
将其与字符串进行比较。所有这些的 Bookshelf/Knex 版本看起来像:
model
.query(function(qb) {
const keyword = "pattern";
qb.whereRaw(`(information->'description')::TEXT LIKE '%${keyword}%'`)
})
.fetch();
显然这部分原始查询不能参数化(至少在 Postgres 中)所以需要 JavaScript 中的字符串替换。这意味着您应该格外小心该字符串的来源(即仅使用有限的子集,或在使用前进行清理),因为您正在绕过 Knex 的常规保护。