查询

BaaS.TableObject#find(options)

参数说明

options(类型:Object),属性说明:

属性类型必填默认说明
withCountbooleantrue是否返回 total_count

withCount 设为 false,接口返回的数据中不包含 total_count,当数据条目多时,可通过不返回 total_count 提高响应速度。如果需要查询记录的总数,请使用 count 方法。

SDK v2.x withCount 的默认值为 true,SDK v3+ withCount 的默认值为 false

数据类型对应查询操作符表

数据类型可使用的查询操作说明
string=, in, notIn, !=, isNull, isNotNull, contains, matches, exists, notExists
integer=, >, >=, <, <=, !=, in, notIn, isNull, isNotNull, exists, notExists
number=, >, >=, <, <=, !=, in, notIn, isNull, isNotNull, exists, notExists
array=, in, notIn, isNull, isNotNull, arrayContains, exists, notExistsfilegeojsonobjectdate 类型的 array 不支持查询操作。如果进行查询,会返回空数组
boolean=, exists, notExists, isNull, isNotNull
date=, >, >=, <, <=, exists, notExists, isNull, isNotNull
fileisNull, isNotNull, exists, notExists
geojsoninclude, within, withinCircle, exists, notExists, isNull, isNotNull请参考地理位置操作章节
object=, hasKey, isNull, isNotNull, exists, notExists
pointer=, in, notIn, !=, isNull, isNotNull, exists, notExists

file、geojson、object、date 类型的 array 不支持查询操作。如果进行查询,会返回空数组

操作步骤

1.通过 数据表 ID数据表名 实例化一个 TableObject 对象,操作该对象即相当于操作对应的数据表,

let MyTableObject = new BaaS.TableObject(tableID | tableName)

参数说明

tableID 和 tableName 二选一,不能同时存在

参数名类型说明
tableIDinteger数据表的 ID
tableNamestring数据表名

2.实例化一个 Query 对象,在该对象上添加查询条件

let query = new BaaS.Query()

查看下面的文档,了解目前支持的查询条件

3.支持查询条件并执行查找操作

MyTableObject.setQuery(query).find()

示例

请求示例

  1. asynnc function query() {
  2. try {
  3. // 实例化查询对象
  4. let query = new BaaS.Query()
  5. // 设置查询条件(比较、字符串包含、组合等)
  6. //...
  7. // 应用查询对象
  8. let Product = new BaaS.TableObject(tableName)
  9. let res = await Product.setQuery(query).find()
  10. // success
  11. return res
  12. // 不设置查询条件
  13. let res = Product.find()
  14. // success
  15. return res
  16. } catch(err) {
  17. // error
  18. throw err
  19. }
  20. }
  1. function query() {
  2. let query = new BaaS.Query()
  3. // 设置查询条件(比较、字符串包含、组合等)
  4. //...
  5. // 应用查询对象
  6. let Product = new BaaS.TableObject(tableName)
  7. Product.setQuery(query).find().then(res => {
  8. // success
  9. callback(null, res)
  10. }).catch(err => {
  11. // error
  12. callback(err)
  13. })
  14. // 不设置查询条件
  15. Product.find().then(res => {
  16. // success
  17. callback(null, res)
  18. }).catch(err => {
  19. // error
  20. callback(err)
  21. })
  22. }

返回示例

res 结构如下

  1. {
  2. "status": 200,
  3. "data": {
  4. "meta": {
  5. "limit": 20,
  6. "next": null,
  7. "offset": 0,
  8. "previous": null,
  9. "total_count": 3
  10. },
  11. "objects": [
  12. {
  13. "_id": "59a3c2b5afb7766a5ec6e84e",
  14. "amount": 0,
  15. "created_at": 1503904437,
  16. "created_by": 36395395,
  17. "desc": ["good", "great"],
  18. "id": "59a3c2b5afb7766a5ec6e84e",
  19. "name": "apple",
  20. "price": 1.0,
  21. "read_perm": ["user:*"],
  22. "updated_at": 1503904437,
  23. "write_perm": ["user:*"]
  24. }
  25. ]
  26. }
  27. }

err 对象结构请参考错误码和 HError 对象

常见错误:

错误码 err.code可能的原因
4001. 指定/过滤输出字段的字段名有误、2. GEO 查询参数有误、3. 查询语法错误
404数据表不存在

比较查询

query.compare(key, operator, value)

operator 包含 =, !=, <, <=, >, >=

  1. query.compare('amount', '>', 1)

多个查询条件

当存在多个查询条件时,它们之间默认为 AND 关系,查询返回满足所有条件的记录,如下示例,

  1. // 查询满足 1 <= amount < 10 的记录
  2. query.compare('amount', '>=', 1)
  3. query.compare('amount', '<', 10)

多个查询条件之间需要更复杂的组合关系,可以查看以下 复杂组合查询 小节

字符串查询

  1. query.contains('name', 'apple')

也支持正则匹配

  1. query.matches('name', regExp)

构建一个 regExp 可通过以下两种方法之一:

  • 使用正则表达式字面量
  1. const regExp = /^abc/i
  • 调用 RegExp 对象的构造函数
  1. const regExp = new RegExp('^abc', 'i')

正则匹配示例

  1. /* 以查找手机号码为例,phoneNumber 字段必须为 string 类型 */
  2. let regExp
  3. // 查找 以 188 开头的手机号码
  4. regExp = /^188/
  5. // 查找 以 708 结尾的手机号码
  6. regx = /708$/
  7. // 查找 以 188 开头的手机号码,以 708 结尾的手机号码
  8. regx = /^188\d+708$/
  9. query.matches('phoneNumber', regx)

数组查询

field 的类型不限制,field 的 value 含有 array 中的一个或多个

  1. query.in(fieldName, array)

field 的类型不限制,field 的 value 不含有 array 中的任何一个

  1. query.notIn(fieldName, array)

field 的类型必须为数组, field 的 value 包含 array 中的每一个

  1. query.arrayContains(fieldName, array)

如果希望查找数组中只包含指定数组中所有的值的记录,可以使用比较查询

  1. query.compare(fieldName, '=', array)

请求示例

  1. /* color 是类型为字符串的字段,desc 是类型为数组的字段 */
  2. // 查询 color 是 green 或 red 或 yellow 的记录
  3. query.in('color', ['green', 'red', 'yellow'])
  4. // 查询 desc 中包含 green 或 red 或 yellow 的记录
  5. query.in('desc', ['green', 'red', 'yellow'])
  6. // 查询 color 不是 green、red 和 yellow 的记录
  7. query.notIn('color', ['green', 'red', 'yellow'])
  8. // 查询 desc 中不包含 green、red 和 yellow 的记录
  9. query.notIn('desc', ['green', 'red', 'yellow'])
  10. // 查询 desc 中包含 green、red 和 yellow 的记录
  11. query.arrayContains('desc', ['green', 'red', 'yellow'])
  12. // 查询 desc 中只包含 green、red 和 yellow 的记录
  13. query.compare('desc', '=', ['green', 'red', 'yellow'])

查询字段值为 null 或非 null 记录

  1. query.isNull('name')
  2. query.isNull(['name', 'price'])
  3. query.isNotNull('name')
  4. query.isNotNull(['name', 'price'])

查询字段值为空或非空记录

  1. query.exists('name')
  2. query.exists(['name', 'price'])
  3. query.notExists('name')
  4. query.notExists(['name', 'price'])

hasKey 查询 (仅限 object 类型)

参数说明

参数类型必填说明
keyString在数据表中的类型必须是 Object
valueString需要检测的属性名, 只能包含字母、数字和下划线,必须以字母开头

示例代码

假设数据表有如下数据行

  1. [
  2. {
  3. 'id': '59a3c2b5afb7766a5ec6e84e',
  4. name: '战争与和平',
  5. publisherInfo: {
  6. name: 'abc出版社',
  7. },
  8. },
  9. {
  10. 'id': '59a3c2b5afb7766a5ec6e84g',
  11. name: '西游记',
  12. publisherInfo: {
  13. name: 'efg出版社',
  14. location: '广东省广州市天河区五山路 100 号'
  15. },
  16. },
  17. ]

查询字段 publisherInfo 中存在 location 属性的数据行

  1. query.hasKey('publisherInfo', 'location')

查询结果

  1. [
  2. {
  3. 'id': '59a3c2b5afb7766a5ec6e84g',
  4. name: '西游记',
  5. publisherInfo: {
  6. name: 'efg出版社',
  7. location: '广东省广州市天河区五山路 100 号'
  8. },
  9. }
  10. ]

注意:目前暂不支持查询内嵌属性

假设数据行如下

  1. [
  2. {
  3. 'id': '59a3c2b5afb7766a5ec6e84g',
  4. name: '西游记',
  5. publisherInfo: {
  6. abc: {
  7. name: 'efg出版社',
  8. location: '广东省广州市天河区五山路 100 号'
  9. }
  10. },
  11. }
  12. ]

则下面的查询语句是非法的

  1. query.hasKey('publisherInfo', 'abc.location')

pointer 查询

目前 pointer 仅支持针对 pointer 本身的查询,不支持嵌套查询(即查询 pointer 指向的数据行的字段)

示例代码

假设现在有两张表: order 表和 customer 表。

order 表部分字段结构如下:

字段名字段类型说明
customerpointer指向了 customer
userpointer指向了 _userprofile

现在需要查询 order 表中,同时满足以下条件的数据行:

  • customer 字段指向 customer 表中 id 为 5bad87ab0769797b4fb27a1b 的数据行
  • user 字段指向了 _userprofile 表中 id 为 69147880 的数据行
  1. async function queryPointer() {
  2. try {
  3. var query = new wx.BaaS.Query()
  4. var Customer = new BaaS.TableObject('customer')
  5. var Order = new BaaS.TableObject('order')
  6. var User = new BaaS.User()
  7. query.compare('customer', '=', Customer.getWithoutData('5bad87ab0769797b4fb27a1b'))
  8. query.compare('user', '=', User.getWithoutData(69147880))
  9. let res = await Order.setQuery(query).expand(['customer', 'user']).find()
  10. // success
  11. return res
  12. } catch(err) {
  13. // error
  14. throw err
  15. }
  16. }
  1. function queryPointer() {
  2. var query = new wx.BaaS.Query()
  3. var Customer = new BaaS.TableObject('customer')
  4. var Order = new BaaS.TableObject('order')
  5. var User = new BaaS.User()
  6. query.compare('customer', '=', Customer.getWithoutData('5bad87ab0769797b4fb27a1b'))
  7. query.compare('user', '=', User.getWithoutData(69147880))
  8. Order.setQuery(query).expand(['customer', 'user']).find().then(res => {
  9. // success
  10. callback(null, res)
  11. }).catch(err => {
  12. // error
  13. callback(err)
  14. })
  15. }

返回示例

res 结构如下:

  1. {
  2. "status": 200,
  3. "data": {
  4. "meta": {
  5. "limit": 20,
  6. "next": null,
  7. "offset": 0,
  8. "previous": null,
  9. "total_count": 1
  10. },
  11. "objects": [{
  12. "_id": "5be3f57840507204ce725fc7",
  13. "created_at": 1541666168,
  14. "created_by": 3,
  15. "id": "5be3f57840507204ce725fc7",
  16. "customer": {
  17. "_table": "customer",
  18. "avatar": "https://gravatar.ifanrx.com/avatar/3510eef2166f5015e5b5c744739f5b82?d=https%3A%2F%2Fcdn.ifanr.cn%2Fifanr%2Fdefault_avatar.png",
  19. "gender": 0,
  20. "id": "5bad87ab0769797b4fb27a1b",
  21. "is_authorized": true,
  22. "nickname": "qwESIbpm",
  23. "updated_at": 1535438854
  24. },
  25. "user": {
  26. "avatar": null,
  27. "created_by": 65816744,
  28. "id": 69147880,
  29. "openid": "oXUfx0FrNAvKUI0xxxxxx",
  30. "unionid": null,
  31. "_table": "_userprofile",
  32. "age": 110,
  33. "is_authorized": false,
  34. "created_at": 1532921460,
  35. "updated_at": 1539683851
  36. },
  37. "read_perm": ["user:*"],
  38. "updated_at": 1541666168,
  39. "write_perm": ["user:*"]
  40. }]
  41. }
  42. }

不使用 expand 方法的示例

  1. // 不使用 expand() 方法, customer 字段不会扩展
  2. Order.setQuery(query).find().then(res => {
  3. })

返回示例:

  1. {
  2. "status": 200,
  3. "data": {
  4. "meta": {
  5. "limit": 20,
  6. "next": null,
  7. "offset": 0,
  8. "previous": null,
  9. "total_count": 1
  10. },
  11. "objects": [{
  12. "_id": "5be3f57840507204ce725fc7",
  13. "created_at": 1541666168,
  14. "created_by": 3,
  15. "id": "5be3f57840507204ce725fc7",
  16. "customer": {
  17. "_table": "customer",
  18. "id": "5bad87ab0769797b4fb27a1b"
  19. },
  20. "read_perm": ["user:*"],
  21. "updated_at": 1541666168,
  22. "write_perm": ["user:*"]
  23. }]
  24. }
  25. }

其他查询 pointer 示例

  1. // in 查询
  2. query.in('customer', [Customer.getWithoutData('5bad87ab0769797b4fb27a1b'), Customer.getWithoutData('5bad87ab0769797b4fb27a1f'), Customer.getWithoutData('5bad87ab0769797b4fb27a11')])
  3. // 查询 user 字段是否存在
  4. query.exist('customer')

pointer 类型支持的查询操作符请参考 数据类型对应查询操作符表

组合查询

  1. let query1 = new BaaS.Query()
  2. query1.isNull('name')
  3. let query2 = new BaaS.Query()
  4. query2.compare('price', '>', 10)
  5. ...
  6. // and 查询
  7. let andQuery = BaaS.Query.and(query1, query2, ...)
  8. // or 查询
  9. let orQuery = BaaS.Query.or(query1, query2, ...)

复杂组合查询

  1. let query1 = new BaaS.Query()
  2. query1.isNull('name')
  3. let query2 = new BaaS.Query()
  4. query2.compare('price', '>', 10)
  5. ...
  6. // and 查询
  7. let andQuery = BaaS.Query.and(query1, query2)
  8. // or 查询中包含 and 查询
  9. let query3 = new BaaS.Query()
  10. query3.compare('amount', '>', 3)
  11. let orQuery = BaaS.Query.or(andQuery, query3)

获取符合筛选条件的数据总数

BaaS.TableObject#count()

  1. async function queryTotal() {
  2. try {
  3. let Product = new BaaS.TableObject(tableName)
  4. let query = new BaaS.Query()
  5. // 设置查询条件
  6. // ...
  7. let num = await Product.setQuery(query).count()
  8. // success
  9. console.log(num) // 10
  10. return res
  11. } catch(err) {
  12. // error
  13. throw err
  14. }
  15. }
  1. function queryTotal() {
  2. let Product = new BaaS.TableObject(tableName)
  3. let query = new BaaS.Query()
  4. // 设置查询条件
  5. // ...
  6. Product.setQuery(query).count().then(num => {
  7. // success
  8. console.log(num) // 10
  9. callback(null, res)
  10. }, err => {
  11. // err
  12. callback(err)
  13. })
  14. }