简体   繁体   English

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

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

What's the proper Loopback filter format to query a value in a MySQL (5.7) JSON field?查询 MySQL (5.7) JSON 字段中的值的正确环回过滤器格式是什么? For example, how would we perform this query using a Loopback REST filter?例如,我们将如何使用 Loopback REST 过滤器执行此查询?

QUERY查询

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

SAMPLE DATA样本数据

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

UNSUCCESSFUL ATTEMPTS失败的尝试

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

Since this question is the first to pop from Google search, and that the loopback mysql connector still does not allow for json querying, I feel like a proper answer should be given for future readers.由于这个问题是第一个从 Google 搜索中弹出的问题,并且回送 mysql 连接器仍然不允许 json 查询,因此我觉得应该为未来的读者提供正确的答案。

The work around is to add the feature directly on the connector by yourself, until the loopback politics settle on a decision on how to really handle it.解决方法是自己直接在连接器上添加该功能,直到环回策略就如何真正处理它做出决定。

Here's our take: put this inside your /connectors folder:这是我们的看法:把它放在你的/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;

Then point to this file in your database config connector: 'connectors/mysql-json' or require it into the connector if that doesn't work (doc says we can define a path but we could not get it working...)然后在你的数据库配置connector: 'connectors/mysql-json'指向这个文件connector: 'connectors/mysql-json'或者如果它不起作用则要求它进入连接器(文档说我们可以定义一个路径但我们无法让它工作......)

This is pretty simple, we overwrite the buildExpression function to be able to insert a new operator json .这很简单,我们覆盖了buildExpression函数以便能够插入一个新的操作符json This will make it usable anywhere you'd use other operators such as gt , lt , nin etc.这将使它在您使用其他运算符(例如gtltnin等)的任何地方都可用。

We went a step further and allow operators be passed in your json operator, to be able to leverage them too.我们更进一步,允许在您的 json 运算符中传递运算符,以便也能够利用它们。

Here's an example query filter:这是一个示例查询过滤器:

{"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

We simply prepend the key of the object passed to json with $.我们只是在传递给json的对象的键前面加上$. for ease of use (not sure if it's the best but works for us).为了便于使用(不确定它是否是最好的,但对我们有用)。 You could write any json path as the key, just ommit the $.您可以编写任何 json 路径作为键,只需省略$.

I don't think this is possible for the moment, i think that neither the connector support the JSON_EXTRACT.我认为目前这是不可能的,我认为连接器都不支持 JSON_EXTRACT。

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

I think that for execute that kind of queries you may use raw queries and write custom code using the actual connector.我认为为了执行这种查询,您可以使用原始查询并使用实际连接器编写自定义代码。

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

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