1

Listed are the following sample documents in a test collection

My requirement is to extract *only" two fields "host.name" and "host.config.storageDevice.scsiLun.lunType" matching the condition that "host.config.storageDevice.scsiLun.lunType" : "cdrom1" and "host.name" : "on-xxx"

Like I mentioned above , I only want attribute "lunType" to be displayed in the array and not "a" or "b"

I attempted to use both $elemMatch and $projection and it always seems to return all the attributes of array "lunType" ... Am I missing anything here

Attempted in reference to documentation http://docs.mongodb.org/manual/reference/projection/elemMatch/

Query

db.test.find({"host.config.storageDevice.scsiLun": { $elemMatch: { "lunType" : "cdrom1" } } },{ "host.name" : 1, "host.config.storageDevice.scsiLun.$" : 1})

db.test.find({"host.config.storageDevice.scsiLun.lunType" : "cdrom1" },{ "host.name" : 1, "host.config.storageDevice.scsiLun.$" : 1})

Documents in collection

    {
    "_id" : ObjectId("51d57f3ad4ebc6c87962d4c0"),
    "host" : {
    "name" : "on-xxx",
    "config" : {
        "storageDevice" : {
            "scsiLun" : [ 
                {
                    "a" : "1",
                    "lunType" : "cdrom1"
                }, 
                {
                    "a" : "2",
                    "lunType" : "disk2"
                }, 
                {
                    "a" : "3",
                    "lunType" : "disk3"
                }
            ]
        }
        }
    }
    }
    , 
    {
    "_id" : ObjectId("51d57f59d4ebc6c87962d4c1"),
    "host" : {
    "name" : "on-yyy",
    "config" : {
        "storageDevice" : {
            "scsiLun" : [ 
                {
                    "a" : "4",
                    "lunType" : "cdrom4"
                }, 
                {
                    "a" : "5",
                    "lunType" : "disk5"
                }, 
                {
                    "a" : "6",
                    "lunType" : "disk6"
                }
            ]
        }
       }
    }
    }
    , 
    {
    "_id" : ObjectId("51d57f74d4ebc6c87962d4c2"),
    "host" : {
    "name" : "on-zzz",
    "config" : {
        "storageDevice" : {
            "scsiLun" : [ 
                {
                    "a" : "7",
                    "lunType" : "cdrom11"
                }, 
                {
                    "a" : "8",
                    "lunType" : "disk22"
                }, 
                {
                    "a" : "9",
                    "lunType" : "disk32"
                }
            ]
        }
    }
    }
    }
4

1 回答 1

2

$elemMatch 所做的只是返回与条件匹配的数组的第一个元素,但它会为您提供整个元素,即“a”和“lunType”属性。

使用$unwind分解数组,然后使用$match过滤和$project仅显示“lunType”字段,聚合可能会得到所需的结果。

我没有测试查询,但它应该如下所示:

    db.test.aggregate(
        { $unwind : "$host.config.storageDevice.scsiLun" },
        { $match : { host.name : "on-xxx" , 
             host.config.storageDevice.scsiLun.lunType : "cdrom1" } },
        { $project : {
            _id : 0 ,
            host.config.storageDevice.scsiLun.lunType : 1 }
    );
于 2013-07-04T15:40:16.233 回答