【问题标题】:Using `filter`, `some`, and `includes` Not Working as Expected in Filtering Docs在过滤文档中使用 `filter`、`some` 和 `includes` 未按预期工作
【发布时间】:2018-12-03 23:15:07
【问题描述】:

我正在使用 filtersomeincludes 的组合在我的 MongoDB/Node 后端环境中返回一组过滤的文档。

虽然我可以让它在一个模拟示例中工作,但当我将它插入到我的实际数据中时,我得到了一个错误。

这是有问题的关键代码:

  let filteredDocs = docs.filter(doc => doc.branches._id.some(branch => mongoArrBranchID.includes(branch._id)));

当我使用以下命令进行控制台注销时:

  console.log("filteredDocs: ", filteredDocs);

我明白了:

原因:TypeError:无法读取未定义的“某些”属性

我一直在挠头,试图找出问题所在。为什么我的模拟示例有效,但不是这个?

我的一个想法是,问题可能在于比较是用不同的类型进行的。因此,我检查了这两行代码,以确保比较在两种情况下都使用 Mongo ObjectID(均返回 true):

console.log("is param value valid: ", mongoose.Types.ObjectId.isValid(mongoArrBranchID[0])); // returns true

console.log("is doc value valid: ", mongoose.Types.ObjectId.isValid(docs[0].branches[0]._id)); // returns true

那么为什么我会在这里收到 TypeError: Cannot read property 'some' of undefined 错误?

顺便说一句,为了让您知道数据是什么样子,我在控制台输出时传入的过滤器值如下所示:

console.log("mongoArrBranchID: ", mongoArrBranchID); // result below 

mongoArrBranchID:  [ 5ac26645121f0613be08185d, 5ac26645121f0613be08185a ]

同样,此检查返回 true:

console.log("is param value valid: ", mongoose.Types.ObjectId.isValid(mongoArrBranchID[0])); // returns true

当我安慰第一个文档时,我的 docs 数据如下所示:

    console.log("doc branches: ", docs[0].branches); // result below

doc branches:  [{"_id":"5ac26645121f0613be08185a","name":"New York"},{"_id":"5ac26645121f0613be08185d","name":"Los Angeles"},{"_id":"5ac26648121f0613be081862","name":"Charlotte"},{"_id":"5ac2664a121f0613be081869","name":"Chicago"},{"_id":"5ac2664a121f0613be08186e","name":"Seattle"}]

当我只输出第一个分支._id 值时,如下所示:

console.log("doc branch: ", docs[0].branches[0]._id);

我明白了:

doc branch:  5ac26645121f0613be08185a

再一次,这个值是否是一个有效的 Mongo 对象 ID 的检查返回 true:

console.log("is doc value valid: ", mongoose.Types.ObjectId.isValid(docs[0].branches[0]._id)); // returns true

那么这里的问题是什么?为什么会出现此错误:

Reason: TypeError: Cannot read property 'some' of undefined

当我这样做时:

  let filteredDocs = docs.filter(doc => doc.branches._id.some(branch => mongoArrBranchID.includes(branch._id)));

  console.log("filteredDocs: ", filteredDocs);

为了进一步说明,当我在 Chrome 中的 ScratchJS 中使用模拟数据时,这对我有用:

let docs = [
  {
    _id: "5ba39a12179b771820413ad8",
    name: "Samson",
    branches: [{ _id: "3nc26645121f0613be08167r", name: "New York" }, { _id: "3fc26645121f0613be08185d", name: "Los Angeles" }, { _id: "2hc26648121f0613be081862", name: "Seattle" }, { _id: "7jc2664a121f0613be081869", name: "Chicago" }, { _id: "7ju2664a121f0613be08186e", name: "Charlotte" }],
    updatedAt: "2018-09-20T13:01:06.709Z",
    createdAt: "2018-09-20T13:01:06.709Z"
  },
  { _id: "3ya39a12179b771820413af5", name: "Sarah", branches: [{ _id: "3nc26645121f0613be08167r", name: "New York" }, { _id: "5ac26645121f0613be08145d", name: "Miami" }, { _id: "5ac2664a121f0613be08154s", name: "Sacramento" }], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" },
  { _id: "2sa39a12179b771820413gy4", name: "Tim", branches: [{ _id: "1rd26645121d5613be08167h", name: "Denver" }, { _id: "5ac2664a121f0613be08154s", name: "Sacramento" }], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }
];

let filterValues = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"];

let filteredDocs = docs.filter(doc => doc.branches.some(branch => filterValues.includes(branch._id)));

console.log(filteredDocs);

那么有什么区别呢?为什么它在模拟示例中有效,但不适用于我的实际数据?

【问题讨论】:

  • let filteredDocs = docs.filter(doc => doc.branches._id.some(branch => mongoArrBranchID.includes(branch._id))); _id 没有 some 方法作为它的字符串。
  • @KunalMukherjee,doc.branches._id 返回 undefined,而不是 string

标签: arrays node.js mongodb


【解决方案1】:

这是因为docs.branches 是一个数组,因此没有您访问过的_id 属性。您应该将代码修改为以下内容:

let filteredDocs = docs.filter(doc => doc.branches.some(branch => mongoArrBranchID.includes(branch._id)));

您收到的错误是因为访问对象的不存在属性返回undefined,因此doc.branches._id 返回undefined,并尝试访问未定义的属性,在这种情况下为some,抛出一个错误。

编辑:

我想澄清一下,错误是您在代码中写了doc.branches._id.some 而不是doc.branches.some。问题在于_id 部分。

【讨论】:

  • 仔细观察,在您的模拟数据示例中,您编写了doc.branches.some,但在您的其他代码中,错误代码中,您编写了doc.branches._id.some。我的代码使用doc.branches.some
  • 你事先声明了mongoArrBranchID吗?在您的模拟数据示例中,您的include 表达式中有filterValues
  • 您能否重申一下我应该在您的代码中查看哪些数据?
  • @Muirik,听起来不错。如果您觉得这个问题已经解决,您应该将答案标记为正确。
  • 我同意这个问题的迭代你的答案是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多