如何在mongodb中查询对象数组的字段? [英] How to query against fields of array of objects in mongodb?

查看:157
本文介绍了如何在mongodb中查询对象数组的字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个mongo集合,其中包含以下文档:

I have a mongo collection which has the following document:

{
    _id: ObjectId("5c7ba3c0e30e6132f8b0c4ef"),
    replies: [
        {
            _id: ObjectId("5c7ba3c0e30e6132f8b0c4ef"),
            status: 'rejected'
        }
    ]
}

我想获得所有已批准状态的答复,因此我进行以下查询:

I want to get all replies with status approved so I make the following query:

Collection.find({'replies.status': 'approved'})

,但上面的文档仍显示在结果中.我在做什么错了?

and yet the document above appears in the results. What am I doing wrong?

推荐答案

这是对查询过程的常见误解.我怀疑您的其中一个文档看起来像这样:

This is a common misunderstanding of the query process. I suspect one of your docs looks like this:

{
    "_id" : 0,
  "replies" : [
  { "_id" : "R0", status: "rejected"}
  ,{ "_id" : "R1", status: "approved"}
  ]
}

问题在于,在数组上执行 find 会匹配至少一个数组条目匹配的文档.它不会将结果过滤为仅这些条目.这是两种方法.鉴于此数据设置:

The issue is that doing a find on an array will match any doc where AT LEAST one of the array entries matches; it does NOT filter the result to JUST those entries. Here are two approaches. Given this data setup:

var r =
[
{
    "_id" : 0,
  "replies" : [
  { "_id" : "R0", status: "rejected"}
  ,{ "_id" : "R1", status: "approved"}
  ]
}
,{
    "_id" : 1,
  "replies" : [
  { "_id" : "R2", status: "rejected"}
  ,{ "_id" : "R3", status: "rejected"}
  ]
}
,{
    "_id" : 2,
  "replies" : [
  { "_id" : "R4", status: "rejected"}
  ,{ "_id" : "R5", status: "approved"}
  ]
}
 ];

方法1:简单且嵌入式数组很小(条目数不超过100或1000s.

Approach 1: Simple and the embedded array is small (dozens not 100s or 1000s of entries.

db.foo.aggregate([
// This will find all docs where ANY of the replies array has AT LEAST ONE      
// entry "approved."   It will NOT filter just those.                           
{$match: {"replies.status": "approved"}}

// Now that we have them, unwind and "refilter"                                 
,{$unwind: "$replies"}

,{$match: {"replies.status": "approved"}}
   ]);

{ "_id" : 0, "replies" : { "_id" : "R1", "status" : "approved" } }
{ "_id" : 2, "replies" : { "_id" : "R5", "status" : "approved" } }

方法2:如果数组很大,则使用 $ filter ,并使用 $ unwind 创建1000份文档.这种方法在保留原始文档的结构中也很有用:

Approach 2: Use $filter if array is very large and using $unwind creates 1000s of docs. This approach also is useful in preserving the structure of the original doc:

db.foo.aggregate([
// This will find all docs where ANY of the replies array has AT LEAST ONE      
// entry "approved."   It will NOT filter just those.                           
{$match: {"replies.status": "approved"}}

// To avoid $unwind, directly filter just "approved" and reset the replies      
// field back into the parent doc:                                              
,{$addFields: {replies: {$filter: {
                input: "$replies",
                as: "zz",
                cond: { $eq: [ "$$zz.status", "approved" ] }
            }}
    }}

   ]);

/*                                                                              
{                                                                               
    "_id" : 0,                                                                  
        "replies" : [                                                           
                     {                                                          
                         "_id" : "R1",                                          
                             "status" : "approved"                              
                             }                                                  
                     ]                                                          
        }                                                                       
{                                                                               
    "_id" : 2,                                                                  
        "replies" : [                                                           
                     {                                                          
                         "_id" : "R5",                                          
                             "status" : "approved"                              
                             }                                                  
                     ]                                                          
        }                                                                       
}        

这篇关于如何在mongodb中查询对象数组的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆