【问题标题】:Searching through JSON data in MySQL in PHP在 PHP 中搜索 MySQL 中的 JSON 数据
【发布时间】:2018-12-30 19:54:48
【问题描述】:

上次我发布了关于搜索JSON data using PHP 的问题。在测试了脚本之后,我想尝试其他的东西。使用 MySQL 搜索数据。因为它比使用 PHP 脚本循环所有内容要快。 我在 PhpMyAdmin 中编写脚本,它为我生成了下一个 PHP 脚本。但是某处有一个错误(悲伤)

"SELECT * 
 FROM `bigtree_pages` 
 WHERE `resources` like \'%\"XNCatDesc\": \"%?%\' and `resources` like \'%\"Brand\": \"%?%\' and `resources` like \'%\"ItemDesc\": \"%?%\'"

我想给出三个值。类别、品牌和 ItemDesc(名称)。但这会引发错误。

您的 SQL 语法有错误;检查手册 对应于您的 MariaDB 服务器版本,以便使用正确的语法 在 '\'%"XNCatDesc": "%'41'%\' 和 resources 附近喜欢 \'%"Brand": "%'none'%\' 和 `reso'

说实话,我真的不知道我必须把 % 符号放在哪里。 例如。我的 JSON 中有这个 "Brand": "Bullet", 该值需要为Brand(因为我们正在搜索品牌)并且品牌是子弹。编写此查询的最佳方式是什么?

【问题讨论】:

  • 这不是你想在 MySQL 中做的事情。 JSON 转义很重要,在这里不容易适应。如果 JSON 数据对您的应用程序非常重要并且您才刚刚开始,请考虑切换到 Postgres,它的 advanced JSON functions 可以完成所有这些以及更多操作。

标签: php mysql json search


【解决方案1】:

要在准备好的查询中使用LIKE 表达式中的参数,您需要形成整个表达式并将其用作参数。否则,您会遇到在值中插入引号时遇到的问题。如果您使用的是mysqli,请尝试这样的操作(假设您的连接称为$conn,而您要搜索的值称为$categorie$brand$itemdesc):

$stmt = $conn->prepare("SELECT * 
                        FROM `bigtree_pages` 
                        WHERE `resources` like ? and `resources` like ? and `resources` like ?");
$search_categorie = "%\"XNCatDesc\": \"%$categorie%\"";
$search_brand = "%\"Brand\": \"%$brand%\"";
$search_itemdesc = "%\"ItemDesc\": \"%$itemdesc%\"";
$stmt->bind_param("sss", $search_categorie, $search_brand, $search_itemdesc);
$stmt->execute();

但是您会遇到的问题是,由于查询中的搜索值(例如$brand)周围有%,因此在搜索brand = X 时,您可以匹配例如

"Brand": "Y", "Other Value": "contains an X"

所以你应该使用正则表达式,例如

$stmt = $conn->prepare("SELECT * 
                        FROM `bigtree_pages` 
                        WHERE `resources` rlike ? AND `resources` rlike ? AND `resources` rlike ?");
$search_categorie = '"XNCatDesc":[[:space:]]+"[^"]*' . $categorie;
$search_brand = '"Brand":[[:space:]]+"[^"]*' . $brand;
$search_itemdesc = '"ItemDesc":[[:space:]]+"[^"]*' . $itemdesc;
$stmt->bind_param("sss", $search_categorie, $search_brand, $search_itemdesc);
$stmt->execute();

如果您运行的是 MySQL 5.7 或更高版本,最好使用内置的 JSON_EXTRACT 函数:

$stmt = $conn->prepare("SELECT * 
                        FROM `bigtree_pages` 
                        WHERE JSON_EXTRACT(`resources`, '$.XNCatDesc') LIKE ? and
                              JSON_EXTRACT(`resources`, '$.Brand') LIKE ? and 
                              JSON_EXTRACT(`resources`, '$.ItemDesc') LIKE ?");
$search_categorie = "%$categorie%";
$search_brand = "%$brand%";
$search_itemdesc = "%$itemdesc%";
$stmt->bind_param("sss", $search_categorie, $search_brand, $search_itemdesc);
$stmt->execute();

【讨论】:

  • 这是一个进步,但这里仍然必须进行额外级别的 JSON 引用。
  • @tadman 我已经在我的本地服务器上测试过了,它按预期工作,你指的是什么?
  • 最后一个带有JSON_EXTRACT 的例子解决了这个问题。我的意思是,如果您要查找文本 'like "this" text',那么您还需要 JSON 引用。
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2015-08-05
  • 2018-09-17
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
相关资源
最近更新 更多