【问题标题】:How to filter documents with a specific field with X nested levels如何过滤具有 X 嵌套级别的特定字段的文档
【发布时间】:2020-04-28 00:45:36
【问题描述】:

我将以一个名为“fooColl”的集合中的两个文档为例:

{
    _id: 1,
    tags: {}
},

{
    _id: 2,
    tags: {
        tagGroup1: {
            tagA: 100,
            tagB: 70
        }
    }
},

{
    _id: 3,
    tags: {
        tagC: 100,
        tagD: 70
    }
},

我在字段“标签”上有几个具有不同嵌套级别的文档,就像这样。

只是为了澄清我在这种特定情况下的逻辑:

Object 1 has the "tags" field with 0 nested levels
Object 2 has the "tags" field with 2 nested levels
Object 3 has the "tags" field with 1 nested level

我需要只过滤具有 tagGroups 的文档,但它们的名称(组)是动态的,这就是我想按嵌套级别过滤的原因。

换句话说,我只需要过滤具有 2 个嵌套级别的“标签”。

【问题讨论】:

  • 会有很多类似tagGroup1,tagGroup2..等的群吗?
  • 您希望它不超过 2 个嵌套级别,还是可以是 2 个或更多嵌套级别?
  • 是的 varman,很多组...当我说它们是动态的时,因为它们会经常变化,所以我无法在我的过滤器中命名它们
  • Michael B,我们只有这3种结构...只有{},只有标签和组+标签

标签: mongodb


【解决方案1】:

此解决方案允许您过滤 2 个或更多 嵌套级别:

db.getCollection('fooColl').aggregate([
    {
        $project: {
            tags: 1,
            tagsArray: { $objectToArray: '$tags' }
        }
    },
    {
        $match: {
            tagsArray: {
                $elemMatch: {
                    k: { $exists: true },
                    v: { $type: 'object' }
                }
            }
        }
    },
    {
        $project: {
            tagsArray: 0
        }
    }
])

$objectToArray 将转换 tags 对象,对于 _id 2 的对象,它看起来像:

"tagsArray" : [{
    "k" : "tagGroup1",
    "v" : { "tagA" : 100, "tagB" : 70 }
}]

$elemMatch 将确保该数组中的至少一个元素符合指定条件。

由于_id 1 的对象没有任何元素,所以会被过滤掉。


$type 查询将过滤所有v 不是对象的文档。

_id 3 的文档将被过滤,因为它看起来像这样:

"tagsArray" : [
{ "k" : "tagC", "v" : 100 },
{ "k" : "tagD",  "v" : 70 }]

但是,此解决方案将匹配以下文档:

{
    "_id" : 4,
    "tags" : {
        "tagGroup1" : {
            "tagA" : { "value" : 100 },
            "tagB" : { "value" : 70 }
        }
    }
}

或者像这样的文件:

{
    "_id" : 4,
    "tags" : {
        "tagC": 100,
        "tagGroup1" : {
            "tagA" : 100
        }
    }
}

【讨论】:

  • 感谢迈克尔!尽管有您警告过的限制,但它正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2022-11-05
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
相关资源
最近更新 更多