【问题标题】:Bookshelf: query builder: how to use like operator with json column?书架:查询生成器:如何将like 运算符与json 列一起使用?
【发布时间】:2020-01-14 01:00:37
【问题描述】:

我正在使用带有 postgresql 数据库的书架

Information 是 json 类型的列。

我想检索所有类似于 '%pattern%' 的列 我使用 sql 查询

select * from table where information::text like '%pattern%';

我想用书架查询生成器来做到这一点

model.query(function(qb) {
  qb.where('information', 'LIKE', '%pattern%')
}).fetch()

但它不起作用,我在bookshelf docs中找不到如何做

有什么想法吗?

【问题讨论】:

  • 为什么要以 JSON 等结构化数据格式进行文本搜索?

标签: json postgresql knex.js bookshelf.js


【解决方案1】:

这里的棘手部分是,尽管您可能认为 JSON(和 JSONB)列是文本,但它们不是!所以没有办法对一个进行LIKE 比较。嗯,有,但您必须先将其转换为字符串:

SELECT * FROM wombats WHERE information #>> '{}' LIKE '%pattern%';

这是一个非常糟糕的想法,请不要这样做!正如@GMB 在 cmets 中指出的那样,JSON 是一种功能强大得多的结构化格式。 Postgres 非常擅长处理 JSON,所以只要问它你需要什么。假设您的值在名为 description 的 JSON 属性中:

SELECT * FROM wombats
  WHERE (information->'description')::TEXT
  LIKE '%pattern%';

在这里,即使我们已经在 J​​SON 对象中识别出正确的属性,它仍以 JSON 类型出现:我们仍然需要将其转换为 ::TEXT,然后再使用 LIKE 将其与字符串进行比较。所有这些的 Bookshelf/Knex 版本如下所示:

model
  .query(function(qb) {
    const keyword = "pattern";
    qb.whereRaw(`(information->'description')::TEXT LIKE '%${keyword}%'`)
  })
  .fetch();

显然这部分原始查询无法参数化(至少在 Postgres 中),因此需要在 JavaScript 中进行字符串替换。这意味着您应该格外小心该字符串的来源(即仅使用有限的子集,或在使用前进行清理),因为您正在绕过 Knex 的常规保护。

【讨论】:

  • 您的示例中是否有错字,它也不起作用 qb.whereRaw(user.informtation->'description')::TEXT LIKE '%?%', 'pattern');
  • 为什么,是的,有:D(看,这就是为什么你不应该复制和粘贴!)我已经编辑添加了尾随引号。请注意,第一个参数中的所有内容都是一个字符串。
  • 仍然无法正常工作我什至添加括号我认为我们错过了一个模型 .query(function(qb) { qb.whereRaw((information->'description')::TEXT LIKE '%?%', 'pattern') }) .fetch();这是错误消息 {"name":"error","length":130,"severity":"ERROR","code":"08P01","file":"postgres.c","line": "1516","例程":"exec_bind_message"}
  • 是的,我马上回去用书架试了一下,它一点也不喜欢它!编辑以提供修改后的解决方案,抱歉出现问题。
  • 是的,它现在可以通过小改动 qb.whereRaw((information)::TEXT LIKE '%${keyword}%')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 2023-02-24
  • 2022-10-01
  • 2020-01-07
  • 2011-03-19
  • 1970-01-01
相关资源
最近更新 更多