繁体   English   中英

如何使用环回 REST API 过滤器查询 MySQL JSON 字段值

[英]How to Query MySQL JSON Field Values with a Loopback REST API Filter

查询 MySQL (5.7) JSON 字段中的值的正确环回过滤器格式是什么? 例如,我们将如何使用 Loopback REST 过滤器执行此查询?

查询

SELECT name, info->"$.id", info->"$.team"
     FROM employee
     WHERE JSON_EXTRACT(info, "$.team") = "A"
     ORDER BY info->"$.id";

样本数据

+---------------------------+----------
| info                      | name
+---------------------------+---------
| {"id": "1", "team": "A"}  | "Sam"  
| {"id": "2", "team": "A"}  | "Julie"
| {"id": "3", "name": "B"}  | "Rob"  
| {"id": "4", "name": "B"}  | "Cindy"
+---------------------------+---------

失败的尝试

/employee?filter[where][info->$.team]=A
/employee?filter[where][info.team]=A
/employee?filter[where][info][team]=A

由于这个问题是第一个从 Google 搜索中弹出的问题,并且回送 mysql 连接器仍然不允许 json 查询,因此我觉得应该为未来的读者提供正确的答案。

解决方法是自己直接在连接器上添加该功能,直到环回策略就如何真正处理它做出决定。

这是我们的看法:把它放在你的/connectors文件夹中:

import * as connector from "loopback-connector-mysql"

var g = require('strong-globalize')();
var SqlConnector = require('loopback-connector').SqlConnector;
var ParameterizedSQL = SqlConnector.ParameterizedSQL;


const _buildExpression = connector.MySQL.prototype.buildExpression;

connector.MySQL.prototype.buildExpression = function (columnName, operator, operatorValue, propertyDefinition) {
  if (operator === 'json') {
    operatorValue = JSON.parse(operatorValue);
    const keys = Object.keys(operatorValue);
    if (keys.length > 1) {
      g.warn('{{MySQL}} {{json}} syntax can only receive one key, received ' + keys.length);
    }
    const jsonPointer = "$." + keys[0];
    const value = operatorValue[keys[0]];
    const column = `JSON_EXTRACT(${columnName}, "${jsonPointer}")`;
    if (value && value.constructor === Object) {
      // this includes another operator, apply it on the built column
      const operator = Object.keys(value)[0];
      return _buildExpression.apply(this, [column, operator, value[operator], propertyDefinition]);
    }
    const clause = `${column} = ?`;
    return new ParameterizedSQL(clause,
      [value]);
  } else {
    return _buildExpression.apply(this, [columnName, operator, operatorValue, propertyDefinition])
  }
};

export default connector;

然后在你的数据库配置connector: 'connectors/mysql-json'指向这个文件connector: 'connectors/mysql-json'或者如果它不起作用则要求它进入连接器(文档说我们可以定义一个路径但我们无法让它工作......)

这很简单,我们覆盖了buildExpression函数以便能够插入一个新的操作符json 这将使它在您使用其他运算符(例如gtltnin等)的任何地方都可用。

我们更进一步,允许在您的 json 运算符中传递运算符,以便也能够利用它们。

这是一个示例查询过滤器:

{"where":
   {
      "jsonProperty":{"json":{"id":1}}
   }
}
// Results in 
// WHERE JSON_EXTRACT('jsonProperty', '$.id') = 1



{"where":
   {
      "jsonProperty":{"json":{"id":{"gt":1}}}
   }
}
// Results in 
// WHERE JSON_EXTRACT(`jsonProperty`, '$.id') > 1

我们只是在传递给json的对象的键前面加上$. 为了便于使用(不确定它是否是最好的,但对我们有用)。 您可以编写任何 json 路径作为键,只需省略$.

我认为目前这是不可能的,我认为连接器都不支持 JSON_EXTRACT。

https://github.com/strongloop/loopback-connector-mysql

我认为为了执行这种查询,您可以使用原始查询并使用实际连接器编写自定义代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM