我在search_analytics集合中关注文档
<resource-file>
现在,我希望获得最近创建的文档所排序的唯一搜索关键字。
这是php代码片段
{ "_id" : 1, "keyword" : "24", "found" : 1, "created_at" : "2018-02-27 18:49:07" }
{ "_id" : 2, "keyword" : "100", "found" : 1, "created_at" : "2018-02-27 18:49:10" }
{ "_id" : 3, "keyword" : "15032040", "found" : 1, "created_at" : "2018-02-27 18:49:42" }
{ "_id" : 4, "keyword" : "100", "found" : 1, "created_at" : "2018-02-27 18:49:55" }
当$ docCount为2时,它会提供以下2个数据。
$result = $collection->aggregate([
['$match' => ['found' => ['$ne' => 0]]],
['$group' => ['_id' => ['keyword' => '$keyword']]],
['$sort' => ['created_id' => -1] ],
['$limit' => (int) $docCount],
['$project' => ['keyword' => '$_id.keyword']]
]);
而我期待结果如下
{
"_id": {
"keyword": "15032040"
},
"keyword": "15032040"
},
{
"_id": {
"keyword": "100"
},
"keyword": "100"
}
这里缺少什么?没有组排序工作正常。
答案 0 :(得分:2)
由于 $group
管道步骤,您正在对从管道中删除的不存在字段进行排序。理想情况下,您希望在 $group
阶段之前进行排序,然后在该组中创建一个有序文档列表,然后您可以 $slice
和 $unwind
进一步深入管道。
请考虑运行以下聚合操作:
$result = $collection->aggregate([
['$match' => ['found' => ['$ne' => 0]]],
['$sort' => ['created_at' => -1 ]],
['$group' => [
'_id' => null,
'keywords' => ['$addToSet' => '$keyword']
]],
['$project' => [
'keyword' => ['$slice' => ['$keywords', (int) $docCount]]
]],
['$unwind' => '$keyword']
])
注意强>
虽然$addToSet
仅确保没有重复项添加到集合中并且不会影响现有的重复元素,但它不保证修改集中元素的特定排序。
答案 1 :(得分:1)
您可以使用以下聚合。
$result = $collection->aggregate([
['$match' => ['found' => ['$ne' => 0]]],
['$sort' => ['created_at' => -1 ]],
['$group' => [
'_id' => '$keyword',
'created_at' => ['$push' => '$created_at']
]],
['$addFields' => ['created_at' => ['$arrayElemAt' => ['$created_at', 0]]]],
['$sort' => ['created_at' => -1 ]],
['$limit' => (int) $docCount]
])
答案 2 :(得分:0)
虽然排序和小组并没有为我合作。我使用php的array_unique
函数解决了这个问题。
完整的解决方案:
$docCount = $this->params()->fromQuery('count');
$storeId = (string) $this->params()->fromQuery('store_id');
$collection = new \MongoDB\Collection($this->getManager(), $this->db, $this->searchAnalytics);
$result = $collection->aggregate([
['$match' => ['store_id' => $storeId, 'found' => ['$ne' => 0]]],
['$sort' => ['created_at' => -1] ]
]);
$array = $result->toArray();
$arr = array_column($array, 'keyword');
$unique = array_unique($arr);
$limited = array_splice($unique, 0, (int)$docCount);