正在分析用户查询

概述

查询分析器的任务是转换 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 默认解析器查询语言的特性和语法。

通用自定义

默认情况下搜索任何术语而不是所有术语

如果用户没有明确指定 ANDOR 条款::

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 通常会超过包含每个 foobar . 但是,用户通常希望包含更多搜索词的文档得分更高。要将解析器配置为生成具有此行为的或组,请使用 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 默认为字段。例如,您可能希望“未筛选”的词同时搜索 titlecontent 领域。

在这种情况下,您可以使用 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 并使用 AndOrNotAndNotAndMaybe 更改令牌模式的关键字参数:

# 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 (插入) sat (删除) cact (转置) ca

如果你想要 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

当用户未显式指定布尔运算符时用于联接子查询的查询类,例如 ANDOR . 这允许您将默认运算符从 ANDOR .

这将是 whoosh.qparser.AndGroupwhoosh.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 模块 有关可用插件的信息。

创建自定义运算符

  • 决定是否需要 PrefixOperatorPostfixOperatorInfixOperator .

  • 创建新的 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)

列表中较早的运算符比列表中较晚的运算符绑定得更紧密。