【问题标题】:Mongoose projection to filter list not working, but native does过滤列表的猫鼬投影不起作用,但本机可以
【发布时间】:2022-01-05 03:45:08
【问题描述】:

我正在尝试使用以下查找查询来查找与具有特定 ID 的“工作”对象相关的对象列表,然后返回所有未设置为非活动(活动 =假)。

在本地使用 mongo shell 或 testing on mongoplayground 可以完美运行。但是我不知道如何让猫鼬玩得很好并返回我期望的结果,我总是得到一个空数组。

我不明白为什么它可以完美地在本地找到,但不能通过猫鼬找到。一定有某种我在文档中找不到的问题或特殊性。我的mongodb版本是5.0.5,我的mongoose版本是6.1.5。

我正在尝试使用的 Mongo 查找查询:

db.objects.find({
  "work": ObjectId("61d50a22eed3f421dc33a220")
},
{
  "form": {
    "$filter": {
      "input": "$form",
      "as": "form",
      "cond": {
        "$ne": [
          "$$form.active",
          false
        ]
      }
    }
  }
})

带有 Projection 的 Mongoose 代码(不工作,返回 []):

export const getWIObjects = async (workID: string) => {
  const objs = await ObjectModel.find({
    work: new mongoose.Types.ObjectId(workID),
  }).select({
    form: {
      $filter: {
        input: "$form",
        as: "form",
        cond: {
          $ne: ["$$form.active", false],
        },
      },
    },
  });
  return objs;
};

没有投影的猫鼬代码(返回数据,但将包括非活动字段):

export const getWIObjects = async (workID: string) => {
  const objs = await ObjectModel.find({
    work: new mongoose.Types.ObjectId(workID),
  });
  return objs;
};

【问题讨论】:

    标签: node.js mongodb mongoose find projection


    【解决方案1】:

    我使用 MongoDB v5.0.6 和 Mongoose v6.2.4 尝试了以下操作,查询返回的结果具有预期的投影

    const projectn = 
        {
            form: {
                $filter: {
                    input: "$form",
                    as: "f",
                    cond: {
                        $ne: [ "$$f.active", false ]
                    }
                }
            }
        };
    const filter = { }; // substitute your filter
    const result = await MyModel.find(filter, projectn);
    

    以下查询(使用不同的语法)也返回了相同的结果。

    const result = await MyModel.find(filter).select(projectn);
    

    注意:这种使用聚合运算符的投影语法至少需要 MongoDB v4.4。

    【讨论】:

    • 我认为这就是我一直在做的事情,所以我不知道为什么它现在可以工作,而以前在删除我拥有的内容并重新实现你放在这里的内容之后它以前不是这样......但我会赢的,谢谢!
    【解决方案2】:

    您在 Mongoose 代码中使用 Projection 编写的内容实际上是返回文档。

    我想为什么你得到一个空数组[],因为你可能正在查询一个不在集合中的无效工作ID。

    请在 find 方法中检查您要查询的 workID。

    【讨论】:

    • 嗨!感谢您的回答,但不幸的是事实并非如此。我正在查询现有文档。在我的最终程序中,如果我删除投影组件,它会完美运行(但在结果中包含非活动字段)。查询直接在 mongo CLI 中 100% 正确运行。
    【解决方案3】:

    尝试为此使用聚合

    const objs = await ObjectModel.aggregate([
        {
            '$match': {
                work: mongoose.Types.ObjectId(workID),
                "form.active": false
            }
        }, {
            '$project': {
                form: {
                    $filter: {
                        input: "$form",
                        as: "f",
                        cond: {
                            $ne: ["$$f.active", false],
                        },
                    },
                },
            }
        }
    ])
    

    在匹配中包含 form.active 键,因为它只会减少匹配查询后的文档数量

    【讨论】:

    • 嗨 Smriti,我稍后会试一试,但你能解释一下为什么在 Mongoose 中不能进行投影时聚合会起作用吗?正如我所说,如果我直接通过 mongo CLI 运行查询,我的查询可以 100% 正确运行,并且我希望 mongoose 和本机 CLI 具有相同的功能。
    • 尝试检查您的 mongoose 版本,因为 mongodb 版本 4.4 支持项目中的过滤器 [docs.mongodb.com/manual/reference/method/db.collection.find/] 根据 mongoose 文档 [mongoosejs.com/docs/compatibility.html] 你的 mongoose 版本应该是 ^5.10.0
    • 您好,是的,如果您查看我的问题,我列出了 mongodb 和 mongoose 的版本。我的 mongodb 版本是 5.0.5,我的 mongoose 版本是 6.1.5。我实际上卸载了两者并安装了最新版本以确保不存在版本差距问题。
    • 来自猫鼬选择文档 [mongoosejs.com/docs/api.html#query_Query-select] 似乎目前不支持选择中的过滤器。
    • 对不起,我显然遗漏了一些东西......我在该页面或我通读文档的其他任何地方都没有看到任何说明此类内容的内容。我很确定我已经从头到尾读过这本书两次了。你能提供一些我可以 CTRL+F 阅读的关键短语吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 2017-09-16
    • 2018-06-02
    • 2020-11-29
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多