【问题标题】:Get a document with only sub documents matching a criteria with mongoose获取仅包含符合 mongoose 条件的子文档的文档
【发布时间】:2017-01-29 01:36:14
【问题描述】:

我有这个猫鼬模型:

var mySubEntitySchema = new Schema({
  property1: String,
  property2: String
});

var myEntitySchema = new Schema({
  name: String,
  sub: [mySubEntitySchema]
});

export var MyEntityModel: mongoose.Model<MyEntityDocument> = mongoose.model<MyEntityDocument>("MyEntity", myEntitySchema);

现在我想获取一个特定的 MyEntityDocument,我有它的 _id,但只有与 property1 = "example" 匹配的子文档。

有什么办法吗?

我尝试了使用 Aggregate 的解决方案,但没有成功:

MyEntityModel.aggregate([
{$match: { "_id": myId, "sub.property1":"example" }},
      {$unwind: "$sub"},
      {$match: { "sub.property1":"example"}},
      {$group: {"_id":"$_id","subs":{$push:"$sub"}}}
    ], (error, result) => {
        console.log("Result = " + JSON.stringify(result));
      }
    });

但它什么也没返回。如果我不将 "_id": myId 放在第一个 $match 子句中,那么我会得到结果,但我只想要与我拥有的 _id 对应的一个结果。

有人知道我该怎么做吗?

编辑:按照要求,这是一个示例。

有了这些数据:

  {
    "_id": "54c12276fcb2488d300795e4",
    "name": "a",
    "sub": [
      {
        "_id": "54c12276fcb2488d300795e0",
        "property1": "example",
        "property2": "something"
      },
      {
        "_id": "54c12276fcb2488d300795e1",
        "property1": "notmuch",
        "property2": "somethingelse"
      },
      {
        "_id": "54c12276fcb2488d300795e2",
        "property1": "notinteresting",
        "property2": "something"
      },
      {
        "_id": "54c12276fcb2488d300795e3",
        "property1": "example",
        "property2": "anotherthing"
      }
    ]
  },
  {
    "_id": "54c12277fcb2488d300795e5",
    "name": "b",
    "sub": [
      {
        "_id": "54c12276fcb2488d300795e6",
        "property1": "example",
        "property2": "word"
      }
    ]
  }

我想要 _id 为“54c12276fcb2488d300795e4”的实体和匹配 property1 =“example”的子文档。所以预期的结果是:

  {
    "_id": "54c12276fcb2488d300795e4",
    "name": "a",
    "sub": [
      {
        "_id": "54c12276fcb2488d300795e0",
        "property1": "example",
        "property2": "something"
      },
      {
        "_id": "54c12276fcb2488d300795e3",
        "property1": "example",
        "property2": "anotherthing"
      }
    ]
  }

【问题讨论】:

  • 你能在这里添加一个样本数据集和你想要的结果吗??
  • @AnanthPai 刚刚编辑以添加示例数据和预期结果。

标签: mongoose subdocument


【解决方案1】:

您可以使用findOne 检索您想要的内容。

MyEntityModel.findOne({_id : myId , "sub.property1" :"example"},{'sub.$' : 1},function(err,result){
    if(!err)
    {
        if(result)
        {
            //result is the document you were searching for
        }
    }
});

{'sub.$' : 1} 将只返回匹配的元素。

通过mongoose query documentation 更好地理解。

【讨论】:

    【解决方案2】:

    除了聚合函数的语法不正确之外,您的查询似乎工作正常并且可以得到结果。请参阅 this 链接了解如何使用 mongoose 编写聚合查询。您不应该像在mongodb console 中那样传递数组。只需传递以逗号分隔的查询,如下面的查询所示。

    MyEntityModel.aggregate(
      {$match: { "_id": myId, "sub.property1":"example" }},
      {$unwind: "$sub"},
      {$match: { "sub.property1":"example"}},
      {$group: {"_id":"$_id","name": {"$first": "$name"}, "subs":{$push:"$sub"}}}
    , (error, result) => {
        console.log("Result = " + JSON.stringify(result));
      }
    });
    

    【讨论】:

    • 仍然对我不起作用,我不知道为什么。如果我不将匹配项放在 _id 上,它就可以正常工作,但是一旦我添加了这个条件,结果就是空的。好吧,在我的真实代码中,我与 _id 不完全匹配,但在另一个属性上,不知道它是否会有所不同?
    • 你能在myId 传递给聚合函数之前分享console.log 的值吗
    • 我简化了我的代码以便更容易理解,所以我并没有真正的 myId 值。但无论如何我的标准是好的,因为事情是这样的:带有“_id”的findOne:myId会返回一个结果。没有 "_id": myId 的聚合返回所有与 sub.property1: "example" 匹配的子文档的文档(并且只有那些子文档) 一旦我将 "_id": myId 添加到聚合中,我突然没有结果。
    猜你喜欢
    • 2017-04-24
    • 2022-01-17
    • 2016-06-28
    • 2017-02-28
    • 2020-07-25
    • 2022-11-24
    • 1970-01-01
    • 2015-10-31
    • 2014-07-01
    相关资源
    最近更新 更多