如何在任意深度搜索时只投影Mongo中的内容?

时间:2017-01-31 15:11:43

标签: mongodb mongodb-query

我有this question的类似问题,它正在任意深度搜索。

但是,我想只检索实际找到的内容和它上面的层次结构,而不是整个文档,它看起来像find()的默认行为

  

如果您未指定投影,则db.collection.find()方法会返回与该查询匹配的所有文档的所有字段

例如,我有一个看起来像这样的对象*:

{
    "_id": 1,
    "template": {
        "a": {
            "node1": {
                "options": {
                    "configuration": "true"
                }
            },
            "node2": {
                "options": {
                    "configuration": "false"
                },
                "a":{
                    "node1": {
                        "options": {
                            "configuration": "false"
                        }
                    }
                },
                "b":{}
            },
            "node3": {
                "options": {
                    "configuration": "false"
                },
                "a":{
                    "node1": {
                        "options": {
                            "configuration": "true"
                        }
                    }
                },
                "b":{}
            }
        },
        "b": {
            "node1": {
                "options": {
                    "configuration": "true"
                },
                "a":{
                    "node1": {
                        "options": {
                            "configuration": "true"
                        }
                    }
                },
                "b":{
                    "node1": {
                        "options": {
                            "configuration": "false"
                        }
                    }
                }
            }            
        }
    }
}

我正在尝试找到configuration = false匹配的所有匹配项,并期望仅检索匹配项及其上方的所有内容,如:

{
    "_id": 1,
    "template": {
        "a": {
            "node2": {
                "options": {
                    "configuration": "false"
                },
                "a": {
                    "node1": {
                        "options": {
                            "configuration": "false"
                        }
                    }
                }
            },
            "node3": {
                "options": {
                    "configuration": "false"
                }
            }
        },
        "b": {
            "node1": {
                "options": {
                    "configuration": "true"   <-- still get this as it has a matching child
                },
                "b": {
                    "node1": {
                        "options": {
                            "configuration": "false" <-- Matches here
                        }
                    }
                }
            }
        }
    }
}

我看了$project,但在这种情况下我只是不知道如何使用它。

OBS:

*在您说出数据结构的方式之前,我明白在没有任何上下文的情况下看起来不是一个好的设计,但是与我提到的问题类似,这些数据也来自某种XML输入(有点),无论如何它已经满足了我们的需求,而且没有办法改变它。

1 个答案:

答案 0 :(得分:0)

您可以使用positional operator '$',如下所示:

db.students.find( { grades: { $elemMatch: {
                                            mean: { $gt: 70 },
                                            grade: { $gt:90 }
                                          } } },
                  { "grades.$": 1 } )

但那只是在一个层面上。

在服务器端执行此操作与在客户端执行此操作相比没有什么大的优势。操作中最难的部分是搜索本身,因此应该尽可能地优化。对于预测,MongoDB只实现了一些基本要求,并为客户端留下了更复杂的东西。

为了优化,我们在每个深度处使用单独的索引进行了单独的查询:

db.brand.ensureIndex({products.navigations.subNavigations._id : 1}, {unique : true, sparse: true, name : "unique.subnavigation1.id"})
db.brand.ensureIndex({products.navigations.subNavigations.subNavigations._id : 1}, {unique : true, sparse: true, name : "unique.subnavigation2.id"})
db.brand.ensureIndex({products.navigations.subNavigations.subNavigations.subNavigations._id : 1}, {unique : true, sparse: true, name : "unique.subnavigation3.id"})