如何在 Mysql X DevAPI 中查询空字段或缺失字段?

问题描述

MysqL X DevAPI 如何查询空字段或缺失字段?

我尝试了 .find("age IS NULL").find("age = null"),但都不起作用。

> db.createCollection('users')
> db.getCollection('users').add({ name: "foo",age: 30 })
> db.getCollection('users').add({ name: "bar",age: null })
> db.getCollection('users').find("age IS NULL")
Empty set (0.0003 sec)
> db.getCollection('users').find("age = null")
Empty set (0.0004 sec)

解决方法

我可以使用 MySQL Shell(我猜这就是您正在使用的)和 Connector/Node.js 重现它。我知道 Connector/Node.js 会向服务器发送正确的数据类型(使用 Shell,您可以使用 --trace-proto 选项进行检查)。

Mysqlx.Crud.Find {
  collection {
    name: "<some_schema>"
    schema: "users"
  }
  data_model: DOCUMENT
  criteria {
    type: OPERATOR
    operator {
      name: "is"
      param {
        type: IDENT
        identifier {
          document_path {
            type: MEMBER
            value: "age"
          }
        }
      }
      param {
        type: LITERAL
        literal {
          type: V_NULL
        }
      }
    }
  }
}

这意味着它是服务器中的一些问题。

在这种情况下,看起来 X DevAPI 表达式没有产生正确的 SQL 查询。如果您查看一般日志,您应该会看到类似

SELECT doc FROM `<some_schema>`.`users` WHERE (JSON_EXTRACT(doc,'$.age') IS NULL)

问题是 JSON_EXTRACT 返回的是 null(JSON 类型)而不是 NULL(SQL“类型”),这是 X 插件的限制。

插件修复此问题的一种方法是将 JSON_EXTRACT() 替换为 JSON_VALUE(),在这种情况下它将返回正确的 NULL 值,但我不知道的影响。

作为一种解决方法,您可以随时使用

session.sql("select doc from `<some_schema>`.`users` where json_value(doc,'$.age') is null").execute()

与此同时,我鼓励您使用 MySQL Server: Document Store: X PluginMySQL Server: Document Store: MySQL Shell 类别报告 https://bugs.mysql.com/ 中的错误。

免责声明:我是 Node.js 的 MySQL X DevAPI 连接器的首席开发人员