Php 获取文档的查找数组计数

Php 获取文档的查找数组计数,php,mongodb,Php,Mongodb,我有两个收藏:单词和短语 每个word文档都有一个短语id数组。每个短语可以是活动的,也可以是非活动的 例如: 单词:{“单词”=>“你好”,短语=>[1,2]}{“单词”=>“表格”,短语=>[2]} 短语:{“id”=>1,“短语”=>“hello world!”,“active”=>1}{“id”=>2,“短语”=>“hello,我已经买了新桌子”,“active”=>0} 我需要得到每个单词的活跃短语数 在php中,我是这样做的: 1.获取所有单词 2.对于每个单词,获取条件为['act

我有两个收藏:单词和短语 每个word文档都有一个短语id数组。每个短语可以是活动的,也可以是非活动的

例如:

单词:
{“单词”=>“你好”,短语=>[1,2]}
{“单词”=>“表格”,短语=>[2]}

短语:
{“id”=>1,“短语”=>“hello world!”,“active”=>1}
{“id”=>2,“短语”=>“hello,我已经买了新桌子”,“active”=>0}

我需要得到每个单词的活跃短语数

在php中,我是这样做的:
1.获取所有单词
2.对于每个单词,获取条件为['active'=>1]

问题:如何在一个请求中获得包含活动短语的单词?我尝试使用MapReduce,但我需要对每个单词进行请求,以获得活动短语的数量。

UPD: 在我的测试集中,有92000个短语和23000个单词。

我已经测试了这两种变体:每个单词都使用php循环,其中我在mongo中获得短语计数和聚合功能。

但我更改了下面逗号中的聚合管道,因为有数据。它是数组,所以我不能在上面使用$match。我在$lookup之后使用$unwind

[ '$unwind'  =>  '$5'],
    [
        '$lookup' =>  [
        'from' =>  'phrases_926ee3bc9fa72b029e028ec90e282072ea0721d1',
            'localField' =>  '5',
            'foreignField' =>  '0',
            'as' =>  'phrases_data'
        ]
    ],
    [ '$unwind'  =>  '$phrases_data'],
    [ '$match'  =>  [ 'phrases_data.3'  =>  77] ], //phrases_data.3 => 77 it is similar to phrases_data.active => 1
    [ '$group'  =>  
        [
            '_id'  =>  ['word'  =>  '$1', 'id'  =>  '$0'],
            'active_count'  =>  [ '$sum'  =>  1]
        ]
    ],
    [ '$match'  =>  [ 'active_count'  =>  ['$gt' => 0]] ],
    [ '$sort'  =>
        [
            'active_count'  => -1
        ]
    ]

问题是$group命令占用了80%的处理时间。它比php循环慢得多。以下是我的测试收集结果:

1. Php loop (get words-> get phrases count for each word): 10 seconds
2. Aggregation function : 20 seconds
您可以使用上述聚合管道:

  • 将词语集合文档中的短语数组作为单独的文档展开
  • 使用非预期短语在短语集合中执行查找(联接)
  • 筛选短语并使用$match检查是否存在活动短语
  • 最后,按单词对短语进行分组,并使用$sum:1进行计数

  • 您的mongo服务器版本和php mongo驱动程序版本是什么?mongo 3.2.,php mongo驱动程序似乎是v1,我不知道,谢谢!我知道聚合框架和诸如“$unwind”之类的功能,但我担心它会非常慢。但若并没有替代验证,我将尝试使用它。你们从单词集合中的主要引用都在数组中。所以放松是最好的方法。
    db.words.aggregate([
        { "$unwind" : "$phrases"},
        {
            "$lookup": {
                "from": "phrases",
                "localField": "phrases",
                "foreignField": "id",
                "as": "phrases_data"
            }
        },
        { "$match" : { "phrases_data.active" : 1} },
        { "$group" : {
            "_id" : "$word",
            "active_count" : { $sum : 1 }
            }
        }
    ]);