Mongodb学习记录

  1. 基础匹配查询:
    • {
        "id_card": "134353387483947"
      }

  2. 确认某字段是否存在

    1. 查询所有存在age字段:

      db.users.find({age: {$exists: true}})
    2. 查询所有不存在age字段:

      db.users.find({name: {$exists: false}})
  3.  多表关联查询:
    • 可以使用aggregation+lookup实现类似mysql的左连接查询,再综合unionWith实现类似mysql的全连接查询;
    • 【左连接】参考语法:

      • [
          {
            $lookup: {
              from: "B",
              localField: "id_card",
              foreignField: "id_card",
              as: "自测指标"
            }
          },
          {
            $match:
              {
                "自测指标.rbc.value": "4.6"
              }
          }
        ]

      • 如使用mongodb compass,配置方式如右图:
    • 【左连接+右连接】实现【全连接】查询语法:

      db.collectionA.aggregate([
        // Left join collectionA with collectionB
        {
          $lookup: {
            from: "collectionB",
            localField: "fieldA",
            foreignField: "fieldB",
            as: "leftJoinResult"
          }
        },
        // Union with the right join result
        {
          $unionWith: {
            coll: "collectionB",
            pipeline: [
              {
                $lookup: {
                  from: "collectionA",
                  localField: "fieldB",
                  foreignField: "fieldA",
                  as: "rightJoinResult"
                }
              },
              // Optionally, format or reshape the rightJoinResult documents
            ]
          }
        },
        // Optional: Further operations such as grouping to handle duplicates
      ]);

    • 使用mongodb compass配置方式如图:
      1. 索引【A 】数量为3,【B】数量为5,全连接返回了两个索引的全部数量的记录数8,每条记录都包含A+B的全部数据;
      2. 参考链接:MongoDB的分组操作,联集合查询(多表查询)_mongodb 命令多个表union-CSDN博客
  4. 在 MongoDB 索引设计中,某些文档的特定字段存在,而另一些文档该字段不存在时,选择将缺失字段设为 null 还是直接不包含该字段,取决于以下几点考虑:
    1. 查询性能

      1. 字段不存在:当文档中字段缺失时,MongoDB 在查询中会视该字段为“不存在”。如果你经常使用 { field: { $exists: true } } 查询,MongoDB 会在索引中记录哪些文档包含该字段,不需要扫描全部数据。

      2. 字段设为 null:如果你将不存在的字段显式设置为 null,你可以直接通过 { field: null } 查询相关文档。在某些情况下(如需要与现有字段 null 值保持一致),使用 null 可能会更方便

    2. 索引大小

      1. 字段不存在:当字段不存在时,索引将不记录该字段。这样索引的大小会相对较小。如果你的文档中大量字段是缺失的,选择不包含该字段可以减少索引的大小和数据库的存储开销。

      2. 字段设为 null:如果将不存在的字段设为 null,这些文档会被包含在索引中,增加索引的大小。不过,如果 null 是有效的查询条件或需要在某些查询中明确区分“无值”和“缺失”,使用 null 更有意义。

    3. 查询复杂性

      1. 字段不存在:如果你明确区分“字段缺失”和“字段值为 null”,那么可以使用 $exists 或类似的查询操作。这样有助于区分那些根本没有该字段的文档和字段值为 null 的文档,减少查询的歧义性

      2. 字段设为 null:如果你希望在查询中将“缺失字段”和“字段值为 null”的情况视为相同,使用 null 会让查询更简单和一致,因为你可以直接通过 { field: null } 查找。

    4. 数据一致性

      1. 如果业务逻辑上不存在字段也被视为“没有值”,可以考虑使用 null,这能在数据结构上保持一致性,让查询和数据处理更直观。

      2. 如果需要严格区分“没有这个字段”和“字段值为空”,可以选择让字段不存在。

    5. 总结建议

      1. 如果你希望通过索引减少存储和加快查询速度,并且能够通过 $exists 等条件处理字段缺失,推荐 不包含字段

      2. 如果查询逻辑中需要统一处理“缺失字段”和“字段为空”,并且希望在查询中简化操作,推荐将缺失字段 设置为 null

      3. 选择哪种方式取决于你的具体查询需求和数据模型设计。

  5. 在 MongoDB 中,当字段不存在 或 字段值设为null 时,查询性能可能会受到哪些影响,以下是相关的几点分析:
    1. 索引的行为

      1. 字段不存在:如果文档中没有某个字段,而你对该字段建立了索引,MongoDB 的索引只会记录那些拥有该字段的文档。如果你进行查询时使用了 { field: { $exists: true } },MongoDB 通过索引可以快速找到包含该字段的文档。然而,如果你使用 { field: { $exists: false } },这种查询无法通过索引快速获取结果,因为它需要扫描整个集合来找出哪些文档不包含该字段。

      2. 字段设为 null:如果你将不存在的字段显式设为 null,查询 { field: null } 将直接使用索引查找所有值为 null 的文档,效率较高。这种方式减少了全表扫描的概率。

    2. 查询性能差异

      1. 存在字段(exists: true)查询:这种查询可以使用索引,性能通常较好,尤其是当索引覆盖大量文档时。查询会直接从索引中找到哪些文档包含该字段,减少全表扫描。

      2. 不存在字段(exists: false)查询:如果查询条件是找出那些没有某个字段的文档,则可能需要进行全表扫描,因为索引中只记录了存在字段的文档,而 MongoDB 无法从索引中直接查出“缺失字段”的文档。这种情况下,性能可能比查找有字段的文档要差一些,特别是在集合规模较大时。

    3. 索引优化

      1. 稀疏索引:如果某个字段在文档中并非总是存在,可以使用 稀疏索引sparse: true)来仅为那些包含该字段的文档建立索引。稀疏索引不包括字段缺失的文档,因此在查询包含字段的文档时,可以提高效率。然而,稀疏索引对于查询缺失字段的文档($exists: false)仍然需要全表扫描。

      2. 复合索引:在多字段查询时,如果某个字段有时存在、有时不存在,可以设计复合索引。比如将一个常见字段与一个稀疏字段结合在一起的复合索引,可能能够帮助优化部分查询。

    4. MongoDB 查询优化

      1. MongoDB 会在查询时尽量利用现有的索引和缓存来优化性能。如果字段不存在,MongoDB 可能不得不执行全表扫描,从而导致查询速度变慢。在这种情况下,如果查询涉及大量字段缺失的文档,使用显式 null 值可能更高效,因为 MongoDB 可以通过索引快速识别这些文档。

    5. 总结:

      1. 如果你的查询主要查找字段存在的文档,字段缺失不会明显影响性能,尤其是使用了合适的索引。

      2. 如果你的查询频繁查找字段不存在的文档(exists: false),则这种查询无法直接利用索引,性能可能下降。考虑通过稀疏索引或调整数据模型来优化。

      3. 如果查询场景对“字段缺失”和“字段为空”的区分不敏感,可以考虑使用 null 代替缺失字段,简化查询并提高查询性能。

      4. 因此,查询是否存在该字段的性能差异取决于你的索引结构和查询模式。

  6. 如果最终为了减少存储和加快查询速度,选择空值字段不存在的形式设计索引,那么查询query如下:
    1. 查询字段存在且有特定值

      1. 如果你希望查询某个字段存在且包含特定值的文档,可以使用以下查询语法:

        db.collection.find({ fieldName: { $exists: true, $eq: "keyword" } })

        这条查询语句表示:
        fieldName: { $exists: true }:确保该字段存在。
        $eq: "keyword":确保该字段的值等于 "keyword"。

    2. 查询字段缺失的文档

      1. 如果要查询字段不存在的文档,可以使用 $exists 操作符:

        db.collection.find({ fieldName: { $exists: false } })

        这条查询语句会返回所有 不包含 fieldName 字段 的文档。

    3. 查询字段存在且不为 null

      1. 如果你需要查询某个字段存在,并且它的值不是 null 或其他空值的情况,可以这样写:

        db.collection.find({ fieldName: { $exists: true, $ne: null } })

        这条查询语句返回包含该字段且该字段的值不为 null 的文档。

    4. 全文搜索特定字段

      1. 如果你想对某个字段进行关键字匹配(例如部分匹配),可以使用 $regex 来进行模糊匹配:

        db.collection.find({ fieldName: { $exists: true, $regex: /keyword/ } })

        这条查询语句会查找所有 fieldName 包含 keyword 的文档,注意这是正则表达式匹配。

    5. 总结

      如果字段值为空时选择该字段不存在,那么查询该字段内容时通常需要加上 $exists: true 的条件,确保查询只会返回那些包含该字段的文档。例如:

      db.collection.find({ fieldName: { $exists: true, $regex: /keyword/ } })

      这样可以确保只查询存在该字段并且匹配指定内容的文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值