【问题标题】:Using "aggregate" to combine a list of all subdocuments that match query?使用“聚合”来组合匹配查询的所有子文档的列表?
【发布时间】:2017-02-04 18:45:19
【问题描述】:

我正在尝试使用 PHP mongo 库来“聚合”这样的数据结构:

{
    "_id": 100,
    "name": "Joe",
    "pets":[
        {
            "name": "Kill me",
            "animal": "Frog"
        },
        {
            "name": "Petrov",
            "animal": "Cat"
        },
        {
            "name": "Joe",
            "animal": "Frog"
        }
    ]
},
{
    "_id": 101,
    "name": "Jane",
    "pets":[
        {
            "name": "James",
            "animal": "Hedgehog"
        },
        {
            "name": "Franklin",
            "animal": "Frog"
        }
}

例如,如果我想获取动物是青蛙的所有子文档。请注意,我不想要所有匹配的“超级文档”(即带有 _id 的那些)。我想要一个如下所示的 ARRAY:

    [
        {
            "name": "Kill me",
            "animal": "Frog"
        },
        {
            "name": "Joe",
            "animal": "Frog"
        },
        {
            "name": "Franklin",
            "animal": "Frog"
        }
     ]

我应该使用什么语法(在 PHP 中)来完成这个?我知道这与聚合有关,但我找不到任何符合此特定场景的内容。

【问题讨论】:

    标签: php mongodb aggregation-framework


    【解决方案1】:

    您可以使用以下聚合。 $match 查找数组的值为Frog$unwind 的文档pets 数组。 $match 其中文档有Frog,最后一步是将group 匹配的文档放入数组中。

    <?php
    
        $mongo = new MongoDB\Driver\Manager("mongodb://localhost:27017");
    
        $pipeline = 
            [
                [   
                    '$match' => 
                        [
                            'pets.animal' => 'Frog',
                        ],
                ],
                [   
                    '$unwind' =>'$pets',
                ],
                [   
                    '$match' => 
                        [
                            'pets.animal' => 'Frog',
                        ],
                ],
                [
                    '$group' => 
                        [
                            '_id' => null,
                            'animals' => ['$push' => '$pets'],
                        ],
                ],
            ];
    
        $command = new \MongoDB\Driver\Command([
            'aggregate' => 'insert_collection_name', 
            'pipeline' => $pipeline
        ]);
    
        $cursor = $mongo->executeCommand('insert_db_name', $command);
    
        foreach($cursor as $key => $document) {
                //do something
        }
    
    ?>
    

    【讨论】:

    • 谢谢,这与我想要的非常接近。但是,我该如何匹配多个字段?例如,我想匹配“动物”和“名称?” (为了争论,我们假设每个字段都有一个任意的第三个字段不需要匹配)。
    • 你需要像[pets.animal' =&gt; 'Frog','pets.name' =&gt; 'Franklin', ], 这样的东西。以下是可在$match 阶段使用的comparisonlogical 运算符列表。
    猜你喜欢
    • 2018-06-13
    • 2014-03-28
    • 2023-03-30
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 2020-08-02
    • 1970-01-01
    相关资源
    最近更新 更多