zangodb 是一个非常强大的 indexeddb 包装器,其实现里 mongodb 的众多语法和概念,让开发者在浏览器端也可以使用 mongodb 的语法,熟悉 mongo 的同学用起来可以说是如鱼得水,非常熟悉的感觉,但是总有不足之处,比如:zangodb 在实现 Collection 的 api 时 ,仅实现里最基础的几个 api,如下: erikolson186.github.io/zangodb/Col…
由此可见,使用起来还是非常的不方便,我通过外部包装的方式增加了 updateOrInsertById,sum,count,max 等扩展,这些都是常用的 api, 但写起来还是相当麻烦的。
扩展类封装
这里没有使用继承的方式,也是有一定原因的,暂不赘述。
// CollectionDcc.ts
import { Callback, Collection, Cursor } from "@insertish/zangodb";
export default class CollectionDcc {
private _collection: Collection;
/**
* 创建一个 CollectionDcc 实例。
* @param collection ZangoDB 的 Collection 对象。
*/
constructor(collection: Collection) {
this._collection = collection;
}
/**
* 执行聚合操作并返回一个游标。
* @param pipeline 聚合管道操作数组。
* @returns 返回执行聚合操作后的游标对象。
*/
public aggregate(pipeline: Object[]): Cursor {
return this._collection.aggregate(pipeline);
}
/**
* 更新匹配指定条件的文档。
* @param expr 更新的查询条件。
* @param spec 更新的字段和值。
* @param cb 回调函数,在更新完成后调用。
* @returns 返回一个 Promise,在更新完成后解析为 void。
*/
public update(expr: Object, spec: Object, cb?: Callback): Promise<void> {
return this._collection.update(expr, spec, cb);
}
/**
* 插入一个或多个文档。
* @param docs 要插入的文档对象或文档对象数组。
* @param cb 回调函数,在插入完成后调用。
* @returns 返回一个 Promise,在插入完成后解析为 void。
*/
public insert(docs: Object | Object[], cb?: Callback): Promise<void> {
return this._collection.insert(docs, cb);
}
/**
* 删除匹配指定条件的文档。
* @param expr 删除的查询条件。
* @param cb 回调函数,在删除完成后调用。
* @returns 返回一个 Promise,在删除完成后解析为 void。
*/
public remove(expr: Object, cb?: Callback): Promise<void> {
return this._collection.remove(expr, cb);
}
/**
* 查找匹配指定条件的文档并返回一个游标。
* @param expr 查询的条件。
* @param projection_spec 投影操作,指定要返回的字段。
* @returns 返回执行查询操作后的游标对象。
*/
public find(expr: Object, projection_spec: Object): Cursor {
return this._collection.find(expr, projection_spec);
}
/**
* 查找并返回匹配指定条件的单个文档。
* @param expr 查询的条件。
* @param projection_spec 投影操作,指定要返回的字段。
* @param cb 回调函数,在查询完成后调用。
* @returns 返回一个 Promise,在查询完成后解析为查询到的文档对象。
*/
public findOne(expr: Object, projection_spec: Object = {}, cb?: Callback): Promise<Object> {
return this._collection.findOne(expr, projection_spec, cb);
}
/**
* 根据指定的条件更新或插入文档。
* 如果指定条件的文档不存在,则插入新文档;如果文档存在,则更新文档。
* @param spec 更新或插入的文档。
* @returns 返回一个 Promise,在更新或插入完成后解析为 void。
*/
public updateOrInsertById(spec: Object): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.count({ _id: spec["_id"] }).then((count) => {
if (count === 0) {
this.insert(spec).then(() => {
resolve();
}).catch((err) => {
reject(err);
});
} else {
this._collection.update({ _id: spec["_id"] }, spec).then(() => {
resolve();
}).catch((err) => {
reject(err);
});
}
}).catch((err) => {
reject(err);
});
});
}
/**
* 计算满足指定条件的文档字段的总和。
* @param expr 指定计算总和的字段和条件。
* @returns 返回一个 Promise,在计算完成后解析为总和值。
*/
public sum(expr: Object): Promise<number> {
return new Promise<number>((resolve, reject) => {
this._collection.aggregate([
{ $match: expr },
{ $group: { _id: null, sum: { $sum: "$value" } } }
]).toArray((err, res) => {
if (err) {
reject(err);
} else {
const result = res.length === 0 ? { sum: 0 } : res[0] as { sum: number };
resolve(result.sum);
}
});
});
}
/**
* 计算满足指定条件的文档数量。
* @param expr 指定计算数量的条件。
* @returns 返回一个 Promise,在计算完成后解析为文档数量。
*/
public count(expr: Object): Promise<number> {
return new Promise<number>((resolve, reject) => {
this._collection.aggregate([
{ $match: expr },
{ $group: { _id: null, count: { $sum: 1 } } }
]).toArray((err, res) => {
if (err) {
reject(err);
} else {
const result = res.length === 0 ? { count: 0 } : res[0] as { count: number };
resolve(result.count);
}
});
});
}
/**
* 计算满足指定条件的文档字段的最大值。
* @param expr 指定计算最大值的字段和条件。
* @returns 返回一个 Promise,在计算完成后解析为最大值。
*/
public max(expr: Object): Promise<number> {
return new Promise<number>((resolve, reject) => {
this._collection.aggregate([
{ $match: expr },
{ $group: { _id: null, max: { $max: "$value" } } }
]).toArray((err, res) => {
if (err) {
reject(err);
} else {
const result = res.length === 0 ? { max: 0 } : res[0] as { max: number };
resolve(result.max);
}
});
});
}
}
该类封装了对 ZangoDB 集合的常用操作,包括、插入、删除、查找、最大值、数量统计、sum 聚合 、更新、更新或插入等。每个方法都提供了详细的注释说明其功能和用法。
扩展调用示例
//localDb.ts
import * as zanGoDb from "@insertish/zangodb/dist/zangodb.min.js";
import CollectionDcc from "@/core/db/CollectionDcc.ts";
let db = new zanGoDb.Db('showDataStore',{images:[],pages:[],apiData:[],dataRemotes:[]});
export const imageCollection = new CollectionDcc(db.collection("images"));
export const pagesCollection = new CollectionDcc(db.collection("pages"));
export const remoteApiDataCollection = new CollectionDcc(db.collection("apiData"));
export const remoteApisCollection = new CollectionDcc(db.collection("dataRemotes"));
数据查询调用示例
import {remoteApisCollection} from "../../../db/localDb";
const handleSubmit = () => {
//这样我们一行代码变实现了更新或插入的调用
remoteApisCollection.updateOrInsertById({...values}).then(() => {
toast.success('保存成功');
isEdit.value = false
reloadList();
}).catch((error) => {
isShow.value = true
toast.error('保存失败' + error);
})
}