过滤列表的猫鼬投影不起作用,但本机可以

Mongoose projection to filter list not working, but native does

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

这在本地使用 mongo shell 或 testing on mongoplayground 时非常有效。但是我无法弄清楚如何让 mongo 玩得很好并且 return 我期望的结果,我总是得到一个空数组。

我不明白为什么它可以完美地在本地找到,而不是通过 mongoose。一定有某种我在文档中没有发现的问题或特殊性。我的 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
        ]
      }
    }
  }
})

Mongo使用投影设置代码(不工作,returning []):

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;
};

Mongo没有投影的代码(returning 数据,但将包括非活动字段):

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

你在带投影的Mongoose代码中写的实际上是返回文件。

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

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

尝试为此使用聚合

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 键,因为它只会减少匹配查询后的文档数量

我使用 MongoDB v5.0.6 和 Mongoose v6.2.4 尝试了以下操作,查询 returns 结果符合预期 projection.

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.