首页 > 其他分享 >查询、更新数组/嵌套对象

查询、更新数组/嵌套对象

时间:2025-01-17 09:25:02浏览次数:1  
标签:20 db 查询 嵌套 numbers 数组 匹配 todos

查询、更新数组/嵌套对象

我们可以对对象、对象中的元素、数组、数组中的元素进行匹配查询,甚至还可以对数组和对象相互嵌套的字段进行匹配查询/更新,下面我们从普通匹配开始讲讲如何进行匹配。

普通匹配

传入的对象的每个 <key, value> 构成一个筛选条件,有多个 <key, value> 则表示需同时满足这些条件,是的关系,如果需要关系,可使用 [command.or]((Command.or))

比如找出未完成的进度 50 的待办事项:

db.collection('todos').where({
  done: false,
  progress: 50
}).get()

匹配记录中的嵌套字段

假设在集合中有如下一个记录:

{
  "style": {
    "color": "red"
  }
}

如果我们想要找出集合中 style.colorred 的记录,那么可以传入相同结构的对象做查询条件或使用 ”点表示法“ 查询:

// 方式一
db.collection('todos').where({
  style: {
    color: 'red'
  }
}).get()

// 方式二
db.collection('todos').where({
  'style.color': 'red'
}).get()

匹配数组

匹配数组

假设在集合中有如下一个记录:

{
  "numbers": [10, 20, 30]
}

可以传入一个完全相同的数组来筛选出这条记录:

db.collection('todos').where({
  numbers: [10, 20, 30]
}).get()

匹配数组中的元素

如果想找出数组字段中数组值包含某个值的记录,那可以在匹配数组字段时传入想要匹配的值。如对上面的例子,可传入一个数组中存在的元素来筛选出所有 numbers 字段的值包含 20 的记录:

db.collection('todos').where({
  numbers: 20
}).get()

匹配数组第 n 项元素

如果想找出数组字段中数组的第 n 个元素等于某个值的记录,那在 <key, value> 匹配中可以以 字段.下标key,目标值为 value 来做匹配。如对上面的例子,如果想找出 number 字段第二项的值为 20 的记录,可以如下查询(注意:数组下标从 0 开始):

db.collection('todos').where({
  'numbers.1': 20
}).get()

更新也是类似,比如我们要更新 _idtest 的记录的 numbers 字段的第二项元素至 30:

db.collection('todos').doc('test').update({
  data: {
    'numbers.1': 30
  },
})

结合查询指令进行匹配

在对数组字段进行匹配时,也可以使用如 lt, gt 等指令,来筛选出字段数组中存在满足给定比较条件的记录。如对上面的例子,可查找出所有 numbers 字段的数组值中存在包含大于 25 的值的记录:

const _ = db.command
db.collection('todos').where({
  numbers: _.gt(25)
}).get()

查询指令也可以通过逻辑指令组合条件,比如找出所有 numbers 数组中存在包含大于 25 的值、同时也存在小于 15 的值的记录:

const _ = db.command
db.collection('todos').where({
  numbers: _.gt(25).and(_.lt(15))
}).get()

匹配并更新数组中的元素

如果想要匹配并更新数组中的元素,而不是替换整个数组,除了指定数组下标外,还可以:

1. 更新数组中第一个匹配到的元素

更新数组字段的时候可以用 字段路径.$ 的表示法来更新数组字段的第一个满足查询匹配条件的元素。注意使用这种更新时,查询条件必须包含该数组字段。

假如有如下记录:

{
  "_id": "doc1",
  "scores": [10, 20, 30]
}
{
  "_id": "doc2",
  "scores": [20, 20, 40]
}

让所有 scores 中的第一个 20 的元素更新为 25:

// 注意:批量更新需在云函数中进行
const _ = db.command
db.collection('todos').where({
  scores: 20
}).update({
  data: {
    'scores.$': 25
  }
})

如果记录是对象数组的话也可以做到,路径如 字段路径.$.字段路径

注意事项:

  • 不支持用在数组嵌套数组
  • 如果用 unset 更新操作符,不会从数组中去除该元素,而是置为 null
  • 如果数组元素不是对象、且查询条件用了 neqnotnin,则不能使用 $

2. 更新数组中所有匹配的元素

更新数组字段的时候可以用 字段路径.$[] 的表示法来更新数组字段的所有元素。

假如有如下记录:

{
  "_id": "doc1",
  "scores": {
    "math": [10, 20, 30]
  }
}

比如让 scores.math 字段所有数字加 10:

const _ = db.command
db.collection('todos').doc('doc1').update({
  data: {
    'scores.math.$[]': _.inc(10)
  }
})

更新后 scores.math 数组从 [10, 20, 30] 变为 [20, 30, 40]

如果数组是对象数组也是可以的,假如有如下记录:

{
  "_id": "doc1",
  "scores": {
    "math": [
      { "examId": 1, "score": 10 },
      { "examId": 2, "score": 20 },
      { "examId": 3, "score": 30 }
    ]
  }
}

可以更新 scores.math 下各个元素的 score 原子自增 10:

const _ = db.command
db.collection('todos').doc('doc1').update({
  data: {
    'scores.math.$[].score': _.inc(10)
  }
})

匹配多重嵌套的数组和对象

上面所讲述的所有规则都可以嵌套使用的,假设我们在集合中有如下一个记录:

{
  "root": {
    "objects": [
      {
        "numbers": [10, 20, 30]
      },
      {
        "numbers": [50, 60, 70]
      }
    ]
  }
}

我们可以如下找出集合中所有的满足 root.objects 字段数组的第二项的 numbers 字段的第三项等于 70 的记录:

db.collection('todos').where({
  'root.objects.1.numbers.2': 70
}).get()

注意,指定下标不是必须的,比如可以如下找出集合中所有的满足 root.objects 字段数组中任意一项的 numbers 字段包含 30 的记录:

db.collection('todos').where({
  'root.objects.numbers': 30
}).get()

更新操作也是类似,比如我们要更新 _idtestroot.objects 字段数组的第二项的 numbers 字段的第三项 为 80:

db.collection('todos').doc('test').update({
  data: {
    'root.objects.1.numbers.2': 80
  },
})

标签:20,db,查询,嵌套,numbers,数组,匹配,todos
From: https://www.cnblogs.com/AtlasLapetos/p/18647492

相关文章

  • GaussDB云原生数据库SQL引擎继承原来openGauss的词法解析,语法解析,查询重写,查询优化和
    云原生数据库SQL引擎继承原来openGauss的词法解析,语法解析,查询重写,查询优化和执行引擎的能力。由于云原生数据库是shareddisk架构,一个事务在一个节点上执行,所以不需要原来分布式根据分布式key进行数据分布,分布式执行和分布式2PC提交的能力。为了支持数据库粒度的异地多活,云原生......
  • 双指针+回文数组
    https://codeforces.com/problemset/problem/1610/B#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'usingll=longlong;usingpii=pair<int,int>;constdoublePI=acos(-1);constintN=2e5+10;constintmod=1e9......
  • python 按时间戳删除32×32数组的前2列和后9列(批量处理多个txt)
    前面是单个txt这次批量处理多个txt将所得结果保存到另一个文件夹Python首先处理一个txt内容中多个时间戳,每个时间戳\d{4}-\d{2}-\d{2}\d{2}:\d{2}:\d{2}$对应32行×32列数组,删除数组前2列和后9列。其次采用第一步方法,批量处理某文件夹内所有txt文件,将结果批量存到另一个文件......
  • 命中索引一定能提高查询速度吗?
    命中索引一定能提高查询速度吗?目录命中索引一定能提高查询速度吗?目录索引的基本原理索引命中与查询性能查询复杂性数据量与索引选择性更新与维护成本过多的索引何时索引能提高查询速度?简单查询高选择性字段适当的索引类型结论答案是否定的,在实际项目中我曾踩过这......
  • 约束.数据库设计.多表查询.事务
    1.约束非空约束:关键字是NOTNULL保证列中所有的数据不能有null值。唯一约束:关键字是UNIQUE保证列中所有数据各不相同。主键约束:关键字是PRIMARYKEY非空且唯一。默认约束:关键字是DEFAULT未指定值则采用默认值。外键约束:关键字是FOREIGNKEY练习根据需求,为表......
  • Day10-后端Web实战——Mysql多表操作&员工列表查询(分页查询)
    目录1.多表关系1.1一对多1.1.1关系实现1.1.2外键约束1.2一对一1.3多对多1.4案例2.多表查询2.1概述2.1.1数据准备2.1.2介绍2.1.3分类2.2内连接2.3外连接2.4子查询2.4.1介绍2.4.2标量子查询2.4.3列子查询2.4.4行子查询2.4.5表子查询2.5案例3.员......
  • 洛谷题单指南-线段树的进阶用法-P3168 [CQOI2015] 任务查询系统
    原题链接:https://www.luogu.com.cn/problem/P3168题意解读:一个任务管理系统,能够查询在某个时间点运行的任务中优先级最小的k个任务的优先级之和。解题思路:由于总时间n不超过100000,考虑针对所有时刻建立可持久化线段树,根节点为root[i]的线段树维护时刻i的任务情况,节点区间表示......
  • 4. rust基础Vec-可变数组
    Vec基本知识定义Vec是一个存储堆分配的数据类型,可以动态改变大小。你可以将元素推送到Vec中,或者从其中删除元素。动态大小不像数组([T;N])那样大小固定,Vec的大小在运行时是可变的。你可以向Vec添加元素,也可以删除元素,甚至将它的容量增加或减少。如何使用Vec1.......
  • 如果在odoo模型中是一对多的字段,或者是计算字段,那么在查询的时候,怎么处理。
    在Odoo中,一对多字段(One2many)和计算字段(Computed)在查询时的处理与普通字段有所不同,因为它们并不直接映射到数据库表中的列。理解如何查询这些字段是非常重要的,下面我会分别介绍如何处理一对多字段和计算字段。1.一对多字段(One2many)一对多字段(One2many)在Odoo中是通过外键......
  • 媒体查询+雪碧图
    <媒体查询>----->媒体查询会根据设备的大小自动识别加载不同的样式     ------><metaname="viewport"content="width=device-width,initial-scale=1.0">这条属性为设置试图宽度,并禁止缩放,媒体查询实现统一网站在不同登录设备中实现不同效果,下面这段代码实现在设......