leancloud-基础存储操作

发表于:2022-02-17 23:54技术,nodejs,serveless热度:91喜欢:0

对象

安装使用

npm install leancloud-storage --save

# debug模式
DEBUG=leancloud* node src/leancloud.js

初始化

const AV = require("leancloud-storage");
const { Query, User, Object } = AV;

AV.init({
  appId: "Xxx",
  appKey: "2233",
  serverURL: "https://plqzch1l.lc-cn-n1-shared.com",
});

新增

// extend 一个Class 相当于一张表
const Config = Object.extend("Config");
const config = new Config();
// 等价于
const config = new Object("Config");

config.set("title", "快递详情");
config.set("key", "book_length");
config.set("value", "11");
config.save().then((res) => {
  console.log(res);
});

查询

const query = new Query("Config");
query.get("620e6d13b2ace54e35218427").then((row) => {
  const key = row.get("key");
  const value = row.get("value");
  const title = row.get("title");
  console.log(title, key, value);
});

修改

// 更新对象
const todo = AV.Object.createWithoutData("Todo", "582570f38ac247004f39c24b");
todo.set("content", "这周周会改到周三下午三点。");
todo.save();

// 查看哪些属性有尚未保存的修改
todo.dirtyKeys(); // ['content']
// 撤回
todo.revert(["content"]);

// 计数器
post.increment("likes", 1);
// 更新数组
// push
AV.Object.add("arrayKey", value);
// 去重添加,位置随机
AV.Object.addUnique("arrayKey", value);
// 从数组字段中删除指定对象的所有实例,如果是普通数组去掉多个,unique数组只去掉一个
AV.Object.remove("arrayKey", value);

删除

// 删除整个
const todo = AV.Object.createWithoutData("Todo", "582570f38ac247004f39c24b");
todo.destroy();

// 删除某个属性
const todo = AV.Object.createWithoutData("Todo", "582570f38ac247004f39c24b");

// priority 属性会被删除
todo.unset("priority");
// 保存对象
todo.save();

关联

const post = new AV.Object("Post");
post.set("title", "饿了……");
post.set("content", "中午去哪吃呢?");
// 创建 comment
const comment = new AV.Object("Comment");
comment.set("content", "当然是肯德基啦!");
// 将 post 设为 comment 的一个属性值
comment.set("parent", post);

// 保存 comment 会同时保存 post
comment.save();

查询

基础查询

const query = new AV.Query("Student");
// 查询lastName为Simith的
query.equalTo("lastName", "Smith");
query.find().then((students) => {
  // students 是包含满足条件的 Student 对象的数组
});

条件查询

// 以下表示and  同时生效
// 不等于
query.notEqualTo("firstName", "Jack");
// 限制 age < 18
query.lessThan("age", 18);
// 限制 age <= 18
query.lessThanOrEqualTo("age", 18);
// 限制 age > 18
query.greaterThan("age", 18);
// 限制 age >= 18
query.greaterThanOrEqualTo("age", 18);

// 最多获取 10 条结果
query.limit(10);

query.first().then((todo) => {
  // todo 是第一个满足条件的 Todo 对象
});
// 跳过前 20 条结果
query.skip(20);

// 分页,每页10个,跳过前20个,相当于第三页
const query = new AV.Query("Todo");
query.equalTo("priority", 2);
query.limit(10);
query.skip(20);

// 排序
// 按 createdAt 升序排列
query.ascending("createdAt");
// 按 createdAt 降序排列
query.descending("createdAt");

// 查找包含 'images' 的对象
query.exists("images");

// 查找不包含 'images' 的对象
query.doesNotExist("images");

// 第一个符合条件的title和content
const query = new AV.Query("Todo");
// 确定字段
query.select(["title", "content"]);
query.first().then((todo) => {
  const title = todo.get("title"); // √
  const content = todo.get("content"); // √
  const notes = todo.get("notes"); // undefined
});

字符串查询

// 相当于 SQL 中的 title LIKE 'lunch%'
query.startsWith("title", "lunch");
// 相当于 SQL 中的 title LIKE '%lunch%'
query.contains("title", "lunch");

// 'title' 不包含 'ticket'(不区分大小写)
const regExp = new RegExp("^((?!ticket).)*$", "i");
query.matches("title", regExp);

数组查询

// 数组属性 tags 包含 工作
query.equalTo("tags", "工作");
// 数组属性长度为 3
query.sizeEqualTo("tags", 3);
// 所有数组属性 tags 同时包含 工作、销售 和 会议
query.containsAll("tags", ["工作", "销售", "会议"]);

统计数量

const query = new AV.Query("Todo");
query.equalTo("isComplete", true);
query.count().then((count) => {
  console.log(`${count} 个 todo 已完成。`);
});

组合查询

// or
const priorityQuery = new AV.Query("Todo");
priorityQuery.greaterThanOrEqualTo("priority", 3);
const isCompleteQuery = new AV.Query("Todo");
isCompleteQuery.equalTo("isComplete", true);
const query = AV.Query.or(priorityQuery, isCompleteQuery);
// and
const startDateQuery = new AV.Query("Todo");
startDateQuery.greaterThanOrEqualTo(
  "createdAt",
  new Date("2016-11-13 00:00:00")
);
const endDateQuery = new AV.Query("Todo");
endDateQuery.lessThan("createdAt", new Date("2016-12-03 00:00:00"));

const query = AV.Query.and(startDateQuery, endDateQuery);

注意事项

  • 不等于和不包含查询(无法使用索引)
  • 通配符在前面的字符串查询(无法使用索引)
  • 有条件的 count(需要扫描所有数据)
  • skip 跳过较多的行数(相当于需要先查出被跳过的那些行)
  • 无索引的排序(另外除非复合索引同时覆盖了查询和排序,否则只有其中一个能使用索引)
  • 无索引的查询(另外除非复合索引同时覆盖了所有条件,否则未覆盖到的条件无法使用索引,如果未覆盖的条件区分度较低将会扫描较多的数据)