跳到主要内容

数据模型-复杂查询

[TOC]

如何使用复杂查询

基本查询示例

APIs示例 - 简单条件查询

查询年龄大于18的学生

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
age: {
$gte: 18
}
}
},
select: { $master: true }
}
});
return result;
};
查看结果
{
"records": [
{
"_id": "BH4UMKTNM6",
"name": "Student Zhang",
"age": 18
},
{
"_id": "BERN1Y59JG",
"name": "zhang2",
"age": 33
}
],
"total": 2
}

可视化开发编辑器示例

查询姓名模糊匹配的zhang的学生

async ({ params }) => {
const data = await $w.cloud.callDataSource({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
name: {
$search: "zhang"
}
}
},
select: { $master: true }
}
});
return data;
}

查询参数说明

逻辑运算符

名称描述
$and使用逻辑 and 连接字段,返回与这两个字段条件匹配的数据
$or使用逻辑 or 连接字段,返回与任一个字段条件匹配的数据

逻辑运算符示例

// $and 示例 - 查询年龄在18-30之间的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and: [
{ age: { $gte: 18 } },
{ age: { $lte: 30 } }
]
}
},
select: { $master: true }
}
});
return result;
};

// $or 示例 - 查询名字包含"zhang"或年龄大于25的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$or: [
{ name: { $search: "zhang" } },
{ age: { $gt: 25 } }
]
}
},
select: { $master: true }
}
});
return result;
};

比较运算符

名称描述适用类型
$eq匹配等于指定值的值字符串,布尔值,数字
$neq匹配所有不等于指定值的值字符串,布尔值,数字
$gt匹配大于指定值的值数字
$gte匹配大于或等于指定值的值数字
$lt匹配小于指定值的值数字
$lte匹配小于或等于指定值的值数字
$in匹配数组中指定的任何值数组
$nin不匹配数组中指定的任何值数组

比较运算符示例

// $in 示例 - 查询年龄为18或20或25的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
age: { $in: [18, 20, 25] }
}
},
select: { $master: true }
}
});
return result;
};

// 组合查询示例 - 查询年龄大于18且名字不是"foo"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and:[
{age: { $gt: 18 }},
{name: { $neq: "foo" }}
]
}
},
select: { $master: true }
}
});
return result;
};

特殊运算符

名称描述适用类型说明
$search模糊查询字符串性能较差,尽量避免使用
$nsearch不包含,会把 null 值查找出来字符串性能较差,尽量避免使用
$empty数据为 null任意类型
$nempty数据不为 null任意类型

$empty,$nempty 在 Flexdb 中,会查询字段不存在和字段值为 null 的两种情况。

特殊运算符示例

// $search 示例 - 模糊查询名字包含"zhang"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
name: { $search: "zhang" }
}
},
select: { $master: true }
}
});
return result;
};

// $empty 示例 - 查询没有填写邮箱的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
email: { $empty: 1 }
}
},
select: { $master: true }
}
});
return result;
};

// 组合查询示例 - 查询有邮箱且名字不包含"test"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and: [
{email: { $nempty: 1 }},
{name: { $nsearch: "test" }}
]
}
},
select: { $master: true }
}
});
return result;
};

列表数据查询($in)

基本用法

$in 操作符用于查询字段值等于指定列表中任意一个值的记录,相当于SQL中的IN操作。

// 查询年龄为18、20或25的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
age: { $in: [18, 20, 25] }
}
},
select: { $master: true }
}
});
return result;
};

字符串列表查询

// 查询名字为"张三"、"李四"或"王五"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
name: { $in: ["张三", "李四", "王五"] }
}
},
select: { $master: true }
}
});
return result;
};

组合查询

// 查询年龄为18或20,且班级为"三年二班"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and:[
{age: { $in: [18, 20] }},
{className: { $eq: "三年二班" }}
]
}
},
select: { $master: true }
}
});
return result;
};

反向查询($nin)

// 查询年龄不为18、20或25的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
age: { $nin: [18, 20, 25] }
}
},
select: { $master: true }
}
});
return result;
};

可视化编辑器示例

async ({ params }) => {
const data = await $w.cloud.callDataSource({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
status: { $in: ["active", "pending"] }
}
}
}
});
return data;
}

特殊场景: 如何忽略条件

  1. 场景1,当客户选择语文和数学时,查询语文和数学课程。
  2. 场景2,当客户不做任何选择时,查询所有课程。如何完成不做任何选择? 只需要设置$in为null即可。
// 场景1
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'course',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
course_name: { $in: ["语文""数学"] }
}
},
select: { $master: true }
}
});
return result;
};
// 场景2
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'course',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
course_name: { $in: null }
}
},
select: { $master: true }
}
});
return result;
};

注意事项

  1. $in 不支持包含null值,查询条件中的null会被自动过滤
  2. 列表可以为空数组,但不会匹配任何记录
  3. 性能考虑:
    • 列表中的值不宜过多(建议不超过100个)
    • 对索引字段使用$in效率更高
  4. MySQL与Flexdb差异:
    • Flexdb支持对数组字段使用$in
    • MySQL需要将$in中的null值单独处理

基本模糊查询

// 简单模糊查询 - 查询名字包含"张"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
name: { $search: "张" }
}
},
select: { $master: true }
}
});
return result;
};

反向模糊查询

// 简单模糊查询 - 查询名字不包含"张"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
name: { $nsearch: "张" }
}
},
select: { $master: true }
}
});
return result;
};

组合模糊查询

// 组合模糊查询 - 查询名字包含"张"且年龄大于18的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and: [
{ name: { $search: "张" } },
{ age: { $gt: 18 } }
]
}
},
select: { $master: true }
}
});
return result;
};

多字段模糊查询

// 多字段模糊查询 - 查询名字或描述包含"优秀"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$or: [
{ name: { $search: "优秀" } },
{ description: { $search: "优秀" } }
]
}
},
select: { $master: true }
}
});
return result;
};

模糊查询与精确查询结合

// 模糊查询与精确查询结合 - 查询班级为"三年二班"且名字包含"张"的学生
module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and: [
{ className: { $eq: "三年二班" } },
{ name: { $search: "张" } }
]
}
},
select: { $master: true }
}
});
return result;
};

注意事项

  1. $search 只能用于字符串类型的字段
  2. 模糊查询性能较差,尽量避免在大数据量场景使用
  3. 模糊查询不支持通配符,如 *?
  4. 对于中文搜索,建议使用2-4个字符作为搜索词,以获得更好的性能

如何查询null值

基本查询方式

1. 使用$eq查询null值

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
email: {
$eq: null
}
}
}
}
});
return result;
};

2. 使用$empty查询null值或不存在字段

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
email: {
$empty: 1
}
}
}
}
});
return result;
};

数据库处理$in差异处理

Flexdb查询示例

Flexdb支持直接使用$in包含null值:

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
email: {
$in: [null, "test@example.com"]
}
}
}
}
});
return result;
};

MySQL查询示例

MySQL需要将$in查询转换为$or条件:

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$or: [
{email: {$in: ["test@example.com"]}},
{email: {$eq: null}}
]
}
}
}
});
return result;
};

组合查询示例

查询null值且满足其他条件

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
$and: [
{email: {$eq: null}},
{age: {$gte: 18}}
]
}
}
}
});
return result;
};

查询非null值

module.exports = async function (params, context) {
const result = await context.callModel({
dataSourceName: 'student',
methodName: 'wedaGetRecordsV2',
params: {
filter: {
where: {
email: {
$nempty: 1
}
}
}
}
});
return result;
};

注意事项

  1. MySQL不支持在$in操作符中包含null值