我在这样的模型中记录所有用户搜索查询:
class SearchLog(models.Model):
query = models.CharField(max_length=512)
datetime = models.DateTimeField(auto_now_add=True, db_index=True)
要获取最多只有一个单词的所有查询,我将创建此查询集:
SearchLog.objects.exclude(query__contains=" ")
我想获得最多包含两个单词的查询。无论如何甚至使用原始sql?
答案 0 :(得分:2)
可以使用regular expression (regex)来实现此目的。这是您描述的文本模式。
例如,要匹配大多数两个单词,正则表达式可能如下所示:
^\S+(\s+\S+)?$
(但视情况而定,你可能需要改变一下)。
\S
代表非空格字符(即没有空格,制表符,新行等)。我们重复这些字符一次或多次(使用+
量词)。接下来,我们允许第二个单词(最后是问号?
的含义)。这个新单词由一个或多个连续间距字符(带有\s+
)和一个或多个非空格字符(带\S+
)组成。插入符号(^
)和美元($
)锚点表示字符串的开头和结尾(没有它,它将匹配至少有一个单词的任何内容)。如前所述,其中一个问题可能就是您所看到的一个单词,因此基于该规范,您可能需要稍微更改正则表达式。
例如,如果没有任何单词的查询也应该匹配,我们必须将其更改为^(\S+(\s+\S+)?)?$
,但是只有间距的字符串仍然不匹配。你会发现很难让模式完全正确,因为它基本上取决于你所看到的" 匹配"什么不是。
您可以使用regex101测试正则表达式。匹配的字符串是突出显示的行。具有三个或更多单词的行不突出显示,因此正则表达式将排除这些。您可以使用此工具测试正则表达式并进行更改,直到它完全符合您的要求。
所以我们可以过滤:
SearchLog.objects.filter(query__regex=r'^\S+(\s+\S+)?$')
正则表达式能够执行相当高级的匹配。然而,在计算机科学中,常用语言的着名" 抽取引理"这指定某些模式族 不能被写为正则表达式(事实上,有些模式系列根本无法与任何程序匹配)。在这里,这并不重要(我认为),但正则表达式因此本身无法匹配程序员所考虑的任何模式。