Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过短语和标签获取文章_Python_Sql_Django_Orm - Fatal编程技术网

Python 通过短语和标签获取文章

Python 通过短语和标签获取文章,python,sql,django,orm,Python,Sql,Django,Orm,我正在搜索我的博客。无论如何,我在实现它时遇到了一些问题 我有两个模型: class Article(models.Model): title = models.CharField(max_length=255) content = models.TextField() class Tag(models.Model): article = models.ForeignKey(Article) content = models.CharField(max_leng

我正在搜索我的博客。无论如何,我在实现它时遇到了一些问题

我有两个模型:

class Article(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()

class Tag(models.Model):
    article = models.ForeignKey(Article)
    content = models.CharField(max_length=255)
实际搜索有两个字段:短语和标记。短语应在
Article.title
Article.content
中查找,但标记应在
tag.content
中查找具有
tag
对象的文章

我也在考试

def test_by_phrase_and_tags(self):
    article_content = "spam"
    tag_content1 = "eggs"
    tag_content2 = "cheese"
    article1 = test_utilities.create_article(content=article_content)
    article2 = test_utilities.create_article(content=article_content)
    test_utilities.create_tag(article1, content=tag_content1)
    test_utilities.create_tag(article2, content=tag_content1)
    test_utilities.create_tag(article2, content=tag_content2)
    response = self.client.get(reverse("blog_search"), {
        "phrase": article_content,
        "tags": "{}, {}".format(tag_content1, tag_content2)
    })
    found_articles = response.context[-1]["found_articles"]
    self.assertEqual(found_articles, [article2])
它创建了两篇内容相同的文章,为两篇文章设置了相同的标签,并且只为第二篇文章设置了唯一的标签

然后我要求文章的内容(两篇文章都应该匹配)和标签(只有第二篇文章应该匹配)。总的来说,我主张只返回第二篇文章

我用原始SQL和Django ORM做了很多尝试,但似乎都不管用

使用子查询:

SELECT * FROM blog_article
WHERE blog_article.content = "spam"
AND blog_article.id IN (
    SELECT blog_tag.article_id FROM blog_tag
    WHERE blog_tag.content = "eggs"
    OR blog_tag.content = "cheese"
);
通过连接:

SELECT * FROM blog_article
JOIN blog_tag
ON blog_article.id = blog_tag.article_id
WHERE blog_article.content = "spam"
AND blog_tag.content = "eggs"
AND blog_tag.content = "cheese";
与ORM相同的和其他的东西


那么,我如何才能获得标题或内容中含有
垃圾邮件
且带有标签的文章呢?我被难住了。

如果我理解正确,那么你正在寻找那些既有标签
鸡蛋
adn
奶酪
又没有标签的文章,那么你可以这样做:

SELECT * 
FROM blog_article a
INNER JOIN
(
   SELECT article_id
   FROM blog_tag
   WHERE content IN ('eggs', 'cheese')
   GROUP BY article_id
   HAVING COUNT(DISTINCT content) = 2
) b ON a.id = b.article_id
WHERE a.content = 'spam';
这个查询背后的想法是,他们称之为,一种方法是子查询所做的:

   SELECT article_id
   FROM blog_tag
   WHERE content IN ('eggs', 'cheese')
   GROUP BY article_id
   HAVING COUNT(DISTINCT content) = 2
以下哪一项是:

   GROUP BY article_id
   HAVING COUNT(DISTINCT content) = 2

这将确保每个分组的
article\u id
,都有两个标签,如果文章有一个标签,那么
计数(不同内容)
=1,这将被消除。

如果我理解正确,那么你要找的是那些同时有两个标签的文章
eggs
adn
cheese
不是一个标签,然后你可以这样做:

SELECT * 
FROM blog_article a
INNER JOIN
(
   SELECT article_id
   FROM blog_tag
   WHERE content IN ('eggs', 'cheese')
   GROUP BY article_id
   HAVING COUNT(DISTINCT content) = 2
) b ON a.id = b.article_id
WHERE a.content = 'spam';
这个查询背后的想法是,他们称之为,一种方法是子查询所做的:

   SELECT article_id
   FROM blog_tag
   WHERE content IN ('eggs', 'cheese')
   GROUP BY article_id
   HAVING COUNT(DISTINCT content) = 2
以下哪一项是:

   GROUP BY article_id
   HAVING COUNT(DISTINCT content) = 2

这将确保每个分组的
文章\u id
都有两个标签,如果文章有一个标签,则
计数(不同内容)
=1,这将被删除。

如果我理解正确,您希望通过
文章。标题
文章。内容
带有短语或标签:

首先为标签模型中的文章定义一个
相关的\u名称

class Tag(models.Model):
    article = models.ForeignKey(Article, related_name='tags')
现在查询:

from django.db.models import Q

# supposed input
phrase = 'my search string'
tags = ['tag1', 'tag2']

articles = Article.objects.filter(
   Q(title__icontains=phrase) |
   Q(content__icontains=phrase)) \
   .filter(tags__content__in=tags) \
   .annotate(num_tags=Count('tags')) \
   .filter(num_tags=len(tags))

如果我理解正确,您希望使用短语或标记按
article.title
article.content
过滤文章:

首先为标签模型中的文章定义一个
相关的\u名称

class Tag(models.Model):
    article = models.ForeignKey(Article, related_name='tags')
现在查询:

from django.db.models import Q

# supposed input
phrase = 'my search string'
tags = ['tag1', 'tag2']

articles = Article.objects.filter(
   Q(title__icontains=phrase) |
   Q(content__icontains=phrase)) \
   .filter(tags__content__in=tags) \
   .annotate(num_tags=Count('tags')) \
   .filter(num_tags=len(tags))


谢谢你的回复。
HAVING COUNT(DISTINCT article_id)=2
line有什么作用?@daGrevis-我修正了我的查询,它没有按我预期的方式工作。现在试试,它会很好用的。行
具有COUNT(DISTINCT article\u id)=2
将确保每个
article\u id
都具有
内容
s
“奶酪”、“鸡蛋”
。如果文章id中有一个而不是两个,那么这个
计数(DISTSINCT article\u id)
将是=1,而这个文章id将被删除。这是一个非常酷的查询,适用于比这篇文章更多的方式+1这真是太酷了!它甚至可以工作!所以下一件事是把它转换成ORM代码…@daGrevis-是的,你是对的。很抱歉,我不知道ORM和您使用sql的方式,但您希望以ORM的方式执行此操作。或者,应该采用其他方式直接执行ORM中的sql。感谢您的回复。
HAVING COUNT(DISTINCT article_id)=2
line有什么作用?@daGrevis-我修正了我的查询,它没有按我预期的方式工作。现在试试,它会很好用的。行
具有COUNT(DISTINCT article\u id)=2
将确保每个
article\u id
都具有
内容
s
“奶酪”、“鸡蛋”
。如果文章id中有一个而不是两个,那么这个
计数(DISTSINCT article\u id)
将是=1,而这个文章id将被删除。这是一个非常酷的查询,适用于比这篇文章更多的方式+1这真是太酷了!它甚至可以工作!所以下一件事是把它转换成ORM代码…@daGrevis-是的,你是对的。很抱歉,我不知道ORM和您使用sql的方式,但您希望以ORM的方式执行此操作。或者,它应该是直接执行sql的其他方式,因为它在您的ORM中。几乎!包含
标题
内容
中的短语并带有标签的文章。请测试我的答案,然后让我知道。我希望这正是你想要的。对不起,不是。你看,我需要选择有标题或内容的文章,比如短语(你的代码就是这样),并且两个标签都有。不幸的是,它没有返回任何结果。只是经过测试,它工作了!谢谢你能看看我的代码,看看为什么它不工作吗?再次感谢!几乎!包含
标题
内容
中的短语并带有标签的文章。请测试我的答案,然后让我知道。我希望这正是你想要的。对不起,不是。你看,我需要选择有标题或内容的文章,比如短语(你的代码就是这样),并且两个标签都有。不幸的是,它没有返回任何结果。只是经过测试,它工作了!谢谢你能看看我的代码,看看为什么它不工作吗?再次感谢!使用原始SQL而不是使用诸如后端之类的预先存在的方法,有什么特别的原因吗?我成功地使用了它,只需很少的设置。@GarryCairns haystack很好,但对于标题和内容内的文章的简单搜索,这只是您在这里建议的额外内容。我没有理由不使用现成的解决方案。我唯一的标准是不想设置额外的服务器或其他东西。我来看看你的解决方案。干草堆看起来已经很有希望了!:)使用原始SQL而不是p有什么特别的原因吗