我有Posts
和Tags
模型,与“属于多个”关联。CakePHP 3.x:查询相关帖子
所以在我的数据库中,我有posts
和tags
表和posts_tags
表post_id
和tag_id
领域。 tags
表具有post_count
字段,显示属于该标签的帖子数量。
当我得到一篇文章,我也得到与它相关的标签。现在
$this->Posts->find()
->contain(['Tags'])
->where(['Posts.id' => $id])
->first());
,对于每一个标签,我想获得的是有标签的帖子,但不包括最初的帖子,整理创建日期(created
场)。 重要的是,每个标签都获得了已经获得的职位以外的职位。
我可以使用一个foreach
和每个标签获取包含它的职位,通过排除初始职位的ID和已经获得的职位。
我想知道如果我可以用单个查询来做到这一点,并有一个工作的例子。
谢谢。
编辑
临时的解决方案,它采用了查询每个标签
首先,我得到的主要职务:
$post = $this->Posts->find()
->contain(['Tags'])
->where(['Posts.id' => $id])
->first();
在这种情况下,后恢复通过它的ID,但你可以做不同的事情。你也可以使用缓存。
重要的东西是$post
变量。
现在(在这里是一个好主意,使用缓存...):
//Tries to gets related posts from cache
$related = Cache::read($cache = sprintf('related_posts_for_%s', $post->id), 'posts');
if(empty($related)) {
$tags = $post->tags;
//Re-orders tags, using the "post_count" field, then based on the popularity of tags
usort($tags, function($a, $b) { return $b['post_count'] - $a['post_count']; });
//Gets only the first 5 tags
$tags = array_slice($tags, 0 , 5);
//This array will be contain the ID to be excluded
$exclude = [$post->id];
//Gets a related post for each tag
//Reveres the tags order, because the tags less popular have less chance to find a related post
foreach(array_reverse($tags) as $tag) {
$post = $this->Posts->find('active')
->select(['id', 'title', 'slug'])
->matching('Tags', function($q) use($tag) {
return $q->where(['Tags.id' => $tag->id]);
})
->where(['Posts.id NOT IN' => $exclude])
->first();
//Adds the post to the related posts and its ID to the IDs to be excluded for the next query
if(!empty($post)) {
$related[] = $post;
$exclude[] = $post->id;
}
}
Cache::write($cache, $related, 'posts');
}
//Related posts
debug($related);
注:此代码后,$post
变量不再包含原来的职位。请注意或为相关帖子使用不同的变量名称。
感谢@arilia 。但我想分开这两个查询。我想这是同样的事情,但使用'匹配()'。这样对吗?但在这种情况下有一个问题:此代码可能需要两次相同的职位? –
我不明白:你在OP中说你只想要一个查询,现在你想要两个。 – arilia
假设我的文章有'a'和'b'标签。另一篇文章有相同的标签。同一篇文章(第二篇)将被获得两次,每个标签? –