【问题标题】:MongoDB: find out query array's element not in databaseMongoDB:找出查询数组的元素不在数据库中
【发布时间】:2021-05-03 08:53:53
【问题描述】:

是否可以找出不在数据库中的查询数组元素?

示例:

const query = ['aaa','bbb','ccc']

数据库中的文档:

[{name:'bbb'},{name:'ccc'}]

我想查找不在数据库中的查询数组元素: 返回结果应该是:

['aaa']

除了查询数组中的每个元素(或批次?)之外,我找不到一些快速的方法来做到这一点

谁有更好的方法?谢谢

【问题讨论】:

    标签: arrays mongodb find


    【解决方案1】:

    查询 -missing- 的东西总是一个更昂贵的操作,也没有“神奇”的查询可以为你做这件事。我推荐使用 Mongo 的 distinct 方法,如下所示:

    const queryArr = ['aaa', 'bbb', 'ccc'];
    const allNames = await db.collection.distinct('name');
    const notInDb = queryArr.filter(e => !allNames.includes(e));
    

    但是,如果您想在 1 db 命令中执行此操作,您可以执行以下操作:

    db.collection.aggregate([
      {
        $group: {
          _id: null,
          names: {
            "$addToSet": "$name"
          }
        }
      },
      {
        "$replaceRoot": {
          "newRoot": {
            results: {
              $filter: {
                input: [
                  "aaa",
                  "bbb",
                  "ccc"
                ],
                as: "datum",
                cond: {
                  $not: {
                    "$setIsSubset": [
                      [
                        "$$datum"
                      ],
                      "$names"
                    ]
                  }
                }
              }
            }
          }
        }
      }
    ])
    

    Mongo Playground

    正如您所知道的,这两种方法都需要您将所有名称加载到内存中,没有办法解决这个问题,如果您的数据库规模对于这些方法来说太大,您将不得不遍历查询输入并通过一。

    const queryArr = ['aaa', 'bbb', 'ccc'];
    
    for (let queryName of queryArr) {
        const found = await db.collection.findOne({name: queryName})
        if (!found) {
            //ding
        }
    }
    

    假设您在name 字段上有一个索引,这应该非常有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多