使用其他字段值作为键查找MongoDB文档字段值

使用其他字段值作为键查找MongoDB文档字段值,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,样本文件: { key: "search", phaseStatus: { search: "Finish", write: "Ongoing" } } 我想搜索有多少文档的phaseStatus是“Finish”,哪个阶段由“key”决定 比如这个文档,键是“search”,所以我想查询“phaseStatus.search”。如果另一张单据的键为“write”,则查询“phaseStatus.write” 我正在尝试使用$filter,但它必须是一个数组

样本文件:

{
  key: "search",
  phaseStatus: {
    search: "Finish",
    write: "Ongoing"    
  }
}
我想搜索有多少文档的phaseStatus是“Finish”,哪个阶段由“key”决定

比如这个文档,键是“search”,所以我想查询“phaseStatus.search”。如果另一张单据的键为“write”,则查询“phaseStatus.write”

我正在尝试使用
$filter
,但它必须是一个数组。 我也试着喜欢它:

collection.aggregations([{
  $match: {
    "phaseStatus.$key": "Finish"
  }
}])

但没有起作用。如何查询动态字段?

您可以尝试以下查询:

查询:

db.collection.aggregate([
    {
        $addFields: {
            phaseStatus: {
                $arrayElemAt: [ // As filter returns an array of object, get first object out of an array 
                    {
                        $filter: {
                            input: { // Converted phaseStatus into an array of objects[{k: key, v : value}]
                                $objectToArray: "$phaseStatus"
                            },
                            cond: { // Match the object which has k = $key's value
                                $eq: [
                                    "$$this.k",
                                    "$key"
                                ]
                            }
                        }
                    },
                    0
                ]
            }
        }
    },
    {
        $addFields: {
            phaseStatus: "$phaseStatus.v" // get the value of v field from phaseStatus object & assign it to phaseStatus field
        }
    },
    {
        $match: {
            phaseStatus: "Finish"
        }
    }
])

测试:

您可以尝试以下查询:

查询:

db.collection.aggregate([
    {
        $addFields: {
            phaseStatus: {
                $arrayElemAt: [ // As filter returns an array of object, get first object out of an array 
                    {
                        $filter: {
                            input: { // Converted phaseStatus into an array of objects[{k: key, v : value}]
                                $objectToArray: "$phaseStatus"
                            },
                            cond: { // Match the object which has k = $key's value
                                $eq: [
                                    "$$this.k",
                                    "$key"
                                ]
                            }
                        }
                    },
                    0
                ]
            }
        }
    },
    {
        $addFields: {
            phaseStatus: "$phaseStatus.v" // get the value of v field from phaseStatus object & assign it to phaseStatus field
        }
    },
    {
        $match: {
            phaseStatus: "Finish"
        }
    }
])

测试:

正常,谢谢!也许这种方式太复杂了,会影响查询性能吗?@songjhh:不,你将处理相同数量的文档,使用动态键,这应该是你的选项,请在字段上设置索引。它可以工作,谢谢!也许这种方式太复杂了,会影响查询性能吗?@songjhh:不,您将处理相同数量的文档,使用dynamic key这应该是您的选项,请在字段上设置索引。