使用 Dexie.js 进行范围查询、多条件查询等复杂操作
Dexie.js 是一个强大的 IndexedDB 封装库,它提供了简洁的 API 来管理和查询浏览器中的本地数据库。在进行范围查询、多条件查询等复杂操作时,Dexie.js 提供了多种方法和工具,可以有效满足需求。
1. 基础设置与数据库初始化
在进行查询之前,需要初始化数据库并定义表结构。
import Dexie from 'dexie';
// 初始化数据库
const db = new Dexie('MyDatabase');
// 定义表和索引
db.version(1).stores({
items: '++id, name, category, price, createdAt', // 定义主键和索引字段
});
// 添加一些示例数据(仅需一次)
async function seedData() {
await db.items.bulkAdd([
{ name: 'Item1', category: 'A', price: 100, createdAt: new Date('2023-01-01') },
{ name: 'Item2', category: 'B', price: 200, createdAt: new Date('2023-02-01') },
{ name: 'Item3', category: 'A', price: 150, createdAt: new Date('2023-03-01') },
{ name: 'Item4', category: 'C', price: 300, createdAt: new Date('2023-04-01') },
]);
}
seedData();
2. 范围查询
Dexie.js 提供 where
方法,可以在索引字段上进行范围查询。
查询价格在 100 到 200 之间的商品
async function rangeQuery() {
const results = await db.items
.where('price')
.between(100, 200, true, true) // 包含边界值
.toArray();
console.log(results);
}
rangeQuery();
查询日期范围内的商品
async function dateRangeQuery() {
const startDate = new Date('2023-01-01');
const endDate = new Date('2023-03-31');
const results = await db.items
.where('createdAt')
.between(startDate, endDate, true, true)
.toArray();
console.log(results);
}
dateRangeQuery();
3. 多条件查询
多条件查询可以通过链式调用、复合索引或过滤来实现。
按类别和价格同时过滤
async function multiConditionQuery() {
const results = await db.items
.where('category')
.equals('A') // 按类别过滤
.and(item => item.price > 100) // 进一步按价格过滤
.toArray();
console.log(results);
}
multiConditionQuery();
使用复合索引进行查询
如果查询频繁,建议使用复合索引优化性能。
修改表结构
db.version(2).stores({
items: '++id, name, [category+price]', // 添加复合索引
});
查询特定类别且价格小于 200 的商品
async function compositeIndexQuery() {
const results = await db.items
.where('[category+price]')
.between(['A', Dexie.minKey], ['A', 200], true, true) // 范围基于复合索引
.toArray();
console.log(results);
}
compositeIndexQuery();
4. 模糊查询
Dexie.js 不直接支持模糊查询,但可以通过过滤实现。
查询名称包含 “Item” 的商品
async function fuzzyQuery() {
const results = await db.items
.filter(item => item.name.includes('Item')) // 自定义过滤
.toArray();
console.log(results);
}
fuzzyQuery();
5. 复杂查询:组合条件
可以将多个条件组合起来,通过 Promise.all
或 filter
实现。
查询价格在 100 到 300 且类别为 “A” 或 “B” 的商品
async function combinedQuery() {
const results = await db.items
.where('price')
.between(100, 300)
.filter(item => ['A', 'B'].includes(item.category)) // 结合多个条件
.toArray();
console.log(results);
}
combinedQuery();
6. 排序与分页
Dexie.js 支持链式排序和分页操作。
按价格升序排列,获取前两条记录
async function sortedAndPagedQuery() {
const results = await db.items
.orderBy('price') // 按价格排序
.limit(2) // 分页限制
.toArray();
console.log(results);
}
sortedAndPagedQuery();
结合范围查询和分页
async function rangeAndPagedQuery() {
const results = await db.items
.where('price')
.between(100, 300)
.offset(1) // 跳过一条记录
.limit(2) // 获取两条记录
.toArray();
console.log(results);
}
rangeAndPagedQuery();
7. 动态查询
在实际应用中,查询条件可能是动态生成的。
根据用户输入动态生成查询
async function dynamicQuery(filters) {
let query = db.items;
if (filters.category) {
query = query.where('category').equals(filters.category);
}
if (filters.minPrice && filters.maxPrice) {
query = query.where('price').between(filters.minPrice, filters.maxPrice, true, true);
}
const results = await query.toArray();
console.log(results);
}
// 示例调用
dynamicQuery({ category: 'A', minPrice: 100, maxPrice: 200 });
总结
Dexie.js 提供了丰富的查询功能,支持范围查询、多条件查询、复合索引等多种复杂操作。在使用过程中,注意以下几点:
- 索引优化:为高频查询字段或组合字段建立索引,提升性能。
- 分页与排序:利用
offset
和limit
实现高效的分页。 - 动态查询:结合业务需求动态生成查询条件。
- 过滤性能:尽量使用索引而非
filter
,避免全表扫描。
通过合理设计表结构和索引,结合 Dexie.js 的灵活 API,可以高效实现各种复杂查询。