正在分析用户查询¶
概述¶
查询分析器的任务是转换 query string 由用户提交到 query objects (对象来自 whoosh.query
模块)。
例如,用户查询:
rendering shading
可能被分析成如下的查询对象:
And([Term("content", u"rendering"), Term("content", u"shading")])
whoosh包含一个功能强大的模块化解析器,用于 whoosh.qparser
模块。默认的解析器实现一种与Lucene附带的查询语言类似的查询语言。但是,通过更改插件或使用诸如 whoosh.qparser.MultifieldParser()
, whoosh.qparser.SimpleParser()
或 whoosh.qparser.DisMaxParser()
您可以更改解析器的工作方式、获取更简单的解析器或更改查询语言语法。
(In previous versions of Whoosh, the query parser was based on pyparsing
. 新的手写解析器不那么脆弱,更灵活。)
注解
请记住,您可以使用中的对象以编程方式直接创建查询对象。 whoosh.query
模块。如果您不处理实际的用户查询,那么最好只构建一个查询字符串来解析它。
使用默认分析器¶
创建一个 whoosh.qparser.QueryParser
对象,将 default field 要搜索和要搜索的索引的架构。
from whoosh.qparser import QueryParser
parser = QueryParser("content", schema=myindex.schema)
小技巧
您可以实例化 QueryParser
对象而不指定架构,但是解析器不会处理用户查询的文本。这对于调试很有用,当您希望了解QueryParser如何构建查询,但不希望只为测试构建模式时。
一旦你拥有了 QueryParser
对象,可以调用 parse()
将查询字符串解析为查询对象:
>>> parser.parse(u"alpha OR beta gamma")
And([Or([Term('content', u'alpha'), Term('content', u'beta')]), Term('content', u'gamma')])
见 query language reference 默认解析器查询语言的特性和语法。
通用自定义¶
默认情况下搜索任何术语而不是所有术语¶
如果用户没有明确指定 AND
或 OR
条款::
physically based rendering
…默认情况下,解析器将单词视为 AND
,表示文档要匹配,所有术语都必须存在:
physically AND based AND rendering
更改解析器以使用 OR
相反,为了使文档匹配,可以出现任何条款,即:
physically OR based OR rendering
…使用配置QueryParser group
keyword argument like this:
from whoosh import qparser
parser = qparser.QueryParser(fieldname, schema=myindex.schema,
group=qparser.OrGroup)
或查询允许您指定包含更多查询词的文档得分更高。例如,如果用户搜索 foo bar
, a document with four occurances of foo
通常会超过包含每个 foo
和 bar
. 但是,用户通常希望包含更多搜索词的文档得分更高。要将解析器配置为生成具有此行为的或组,请使用 factory()
类方法 OrGroup
::
og = qparser.OrGroup.factory(0.9)
parser = qparser.QueryParser(fieldname, schema, group=og)
争论的焦点 factory()
是奖金的比例因子(介于0和1之间)。
默认情况下允许用户搜索多个字段¶
默认的QueryParser配置采用不带显式字段的术语,并将它们分配给创建对象时指定的默认字段,例如,如果使用以下方式创建对象:
parser = QueryParser("content", schema=myschema)
用户输入查询:
three blind mice
解析器将其视为:
content:three content:blind content:mice
但是,您可能希望让用户搜索 multiple 默认为字段。例如,您可能希望“未筛选”的词同时搜索 title
和 content
领域。
在这种情况下,您可以使用 whoosh.qparser.MultifieldParser
. 这与普通的QueryParser类似,但它不是默认的字段名字符串,而是 sequence 字段名的数目:
from whoosh.qparser import MultifieldParser
mparser = MultifieldParser(["title", "content"], schema=myschema)
When this MultifieldParser instance parses three blind mice
,它将其视为:
(title:three OR content:three) (title:blind OR content:blind) (title:mice OR content:mice)
简化查询语言¶
一旦你有了一个解析器:
parser = qparser.QueryParser("content", schema=myschema)
您可以使用 remove_plugin_class()
方法。
例如,要删除用户指定要搜索的字段的功能,请执行以下操作:
parser.remove_plugin_class(qparser.FieldsPlugin)
要删除搜索通配符的功能,这可能会对查询性能造成危害:
parser.remove_plugin_class(qparser.WildcardPlugin)
见 qparser 模块 有关whoosh的查询分析器所包含插件的信息。
更改and、or、and not、andmaybe和not语法¶
默认的解析器为and、or、and not、andmaybe和not函数使用英文关键字:
parser = qparser.QueryParser("content", schema=myschema)
可以替换默认值 OperatorsPlugin
对象以用自己的正则表达式替换默认的英语标记。
这个 whoosh.qparser.OperatorsPlugin
实现在查询中使用and、or、not、and not和andmaybe子句的能力。您可以实例化一个新的 OperatorsPlugin
并使用 And
, Or
, Not
, AndNot
和 AndMaybe
更改令牌模式的关键字参数:
# Use Spanish equivalents instead of AND and OR
op = qparser.OperatorsPlugin(And=" Y ", Or=" O ")
parser.replace_plugin(op)
此外,还可以更改 NOT
操作员:
np = qparser.OperatorsPlugin(Not=' NO ')
parser.replace_plugin(np)
参数可以是模式字符串或预编译的正则表达式对象。
例如,要更改默认的解析器,使其使用排版符号,而不是AND、OR、AndNot、AndMaybe和Not函数的单词:
parser = qparser.QueryParser("content", schema=myschema)
# These are regular expressions, so we have to escape the vertical bar
op = qparser.OperatorsPlugin(And="&", Or="\\|", AndNot="&!", AndMaybe="&~", Not="\\-")
parser.replace_plugin(op)
加上小于、大于等。¶
通常,在一个大于“apple”的字段中匹配所有术语的方式是使用一个开放的范围:
field:{apple to]
这个 whoosh.qparser.GtLtPlugin
允许您这样指定相同的搜索:
field:>apple
该插件允许您使用 >
, <
, >=
, <=
, =>
或 =<
在字段说明符之后,并将表达式转换为等效范围::
date:>='31 march 2001'
date:[31 march 2001 to]
添加模糊术语查询¶
模糊查询有助于捕捉拼写错误和类似的单词。这个 whoosh.qparser.FuzzyTermPlugin
允许您搜索“模糊”术语,即不必完全匹配的术语。模糊术语将在一定数量的“编辑”(字符插入、删除和/或换位)内匹配任何类似术语,这称为“Damerau-Levenshtein编辑距离”)。
添加模糊插件:
parser = qparser.QueryParser("fieldname", my_index.schema)
parser.add_plugin(qparser.FuzzyTermPlugin())
将模糊插件添加到解析器后,可以通过添加 ~
然后是可选的最大编辑距离。如果不指定编辑距离,则默认为 1
.
例如,以下“模糊”术语查询:
cat~
将匹配 cat
例如,在cat的一个“edit”中,索引中的所有术语 cast
(插入) s
) at
(删除) c
) act
(转置) c
和 a
)
如果你想要 cat
相配 bat
,需要两次编辑(删除 c
并插入 b
)因此,您需要将最大编辑距离设置为 2
::
cat~2
由于您允许的每个附加编辑都会增加必须检查的可能性的数量,因此编辑的距离大于 2
可能非常慢。
要求模糊项的前几个字符完全匹配通常很有用。这叫做前缀。可以通过在编辑距离后添加斜线和数字来设置前缀的长度。例如,要使用最大编辑距离 2
前缀长度为 3
::
johannson~2/3
可以指定前缀而不指定编辑距离::
johannson~/3
默认前缀距离为 0
.
允许复杂短语查询¶
默认的解析器设置允许短语(接近)查询,例如:
"whoosh search library"
默认短语查询标记了引号之间的文本,并创建了对这些词的邻近搜索。
如果要进行更复杂的邻近搜索,可以用 whoosh.qparser.SequencePlugin
,允许在引号之间进行任何查询。例如::
"(john OR jon OR jonathan~) peters*"
序列语法允许您添加“slop”因子,就像常规短语那样:
"(john OR jon OR jonathan~) peters*"~2
用序列插件替换默认短语插件:
parser = qparser.QueryParser("fieldname", my_index.schema)
parser.remove_plugin_class(qparser.PhrasePlugin)
parser.add_plugin(qparser.SequencePlugin())
或者,可以保留默认短语插件,并在创建序列插件时为开始/结束标记指定正则表达式,从而为序列插件提供不同的语法。正则表达式应具有命名组 slop
对于坡度系数。例如::
parser = qparser.QueryParser("fieldname", my_index.schema)
parser.add_plugin(qparser.SequencePlugin("!(~(?P<slop>[1-9][0-9]*))?"))
这将允许您同时使用常规短语查询和顺序查询:
"regular phrase" AND !sequence query~2!
高级自定义¶
QueryParser参数¶
QueryParser支持两个额外的关键字参数:
group
当用户未显式指定布尔运算符时用于联接子查询的查询类,例如
AND
或OR
. 这允许您将默认运算符从AND
到OR
.这将是
whoosh.qparser.AndGroup
或whoosh.qparser.OrGroup
类(*not*不是一个实例化的对象),除非您已经编写了自己要使用的自定义分组语法。termclass
用于包装单个术语的查询类。
这一定是
whoosh.query.Query
子类(*not*一个实例化的对象),它接受字段名字符串和术语文本unicode字符串__init__
方法。默认值为whoosh.query.Term
.如果要将默认术语类更改为
whoosh.query.Variations
或者,如果您编写了一个自定义术语类,您希望解析器使用它而不是随whoosh一起提供的类。
>>> from whoosh.qparser import QueryParser, OrGroup
>>> orparser = QueryParser("content", schema=myschema, group=OrGroup)
配置插件¶
查询分析器的功能由一组插件提供。您可以删除插件以删除功能,添加插件以添加功能,或者用重新配置或重写的版本替换默认插件。
这个 whoosh.qparser.QueryParser.add_plugin()
, whoosh.qparser.QueryParser.remove_plugin_class()
和 whoosh.qparser.QueryParser.replace_plugin()
方法允许您在 QueryParser
对象。
见 qparser 模块 有关可用插件的信息。
创建自定义运算符¶
决定是否需要
PrefixOperator
,PostfixOperator
或InfixOperator
.创建新的
whoosh.qparser.syntax.GroupNode
子类以保存受运算符影响的节点。此对象负责生成whoosh.query.Query
与语法对应的对象。为运算符的查询语法创建正则表达式模式。
创建一个
OperatorsPlugin.OpTagger
以上信息中的对象。创建新的
OperatorsPlugin
使用自定义运算符配置的实例。替换默认值
OperatorsPlugin
在解析器中使用新实例。
例如,如果您正在创建 BEFORE
操作员:
from whoosh import qparser, query
optype = qparser.InfixOperator
pattern = " BEFORE "
class BeforeGroup(qparser.GroupNode):
merging = True
qclass = query.Ordered
为操作员创建Optager::
btagger = qparser.OperatorPlugin.OpTagger(pattern, BeforeGroup,
qparser.InfixOperator)
默认情况下,中缀运算符是左关联的。要创建右关联中缀运算符,请执行以下操作:
btagger = qparser.OperatorPlugin.OpTagger(pattern, BeforeGroup,
qparser.InfixOperator,
leftassoc=False)
创建一个 OperatorsPlugin
使用新的运算符实例,并替换查询分析器中的默认运算符插件:
qp = qparser.QueryParser("text", myschema)
my_op_plugin = qparser.OperatorsPlugin([(btagger, 0)])
qp.replace_plugin(my_op_plugin)
请注意,使用第一个参数指定的运算符列表是默认运算符(和、或等)的补充。要关闭其中一个默认运算符,可以将none传递给相应的关键字参数::
cp = qparser.OperatorsPlugin([(optagger, 0)], And=None)
如果只需要运算符列表,而不需要任何默认运算符,请使用 clean
关键字参数:
cp = qparser.OperatorsPlugin([(optagger, 0)], clean=True)
列表中较早的运算符比列表中较晚的运算符绑定得更紧密。