def build_keywords_query(keywords): """ Build parsers for a query. :param MultiDict keywords: The search texts keyed by scope key. If empty, the query will match every documents. """ queries = [] if keywords: composer = current_app.config['KERKO_COMPOSER'] text_plugins = [ plugins.PhrasePlugin(), plugins.GroupPlugin(), plugins.OperatorsPlugin( And=r"(?<=\s)" + re.escape(gettext("AND")) + r"(?=\s)", Or=r"(?<=\s)" + re.escape(gettext("OR")) + r"(?=\s)", Not=r"(^|(?<=(\s|[()])))" + re.escape(gettext("NOT")) + r"(?=\s)", AndNot=None, AndMaybe=None, Require=None ), plugins.BoostPlugin(), ] for key, value in keywords.items(multi=True): fields = [spec.key for spec in composer.fields.values() if key in spec.scopes] if not fields: raise KeyError # No known field for that scope key. parser = MultifieldParser( fields, schema=composer.schema, plugins=text_plugins ) queries.append(parser.parse(value)) else: queries.append(Every()) return And(queries)
def test_custom_tokens(): qp = qparser.QueryParser("text", None) qp.remove_plugin_class(plugins.OperatorsPlugin) cp = plugins.OperatorsPlugin(And="&", Or="\\|", AndNot="&!", AndMaybe="&~", Not="-") qp.add_plugin(cp) q = qp.parse("this | that") assert_equal(q.__class__, query.Or) assert_equal(q[0].__class__, query.Term) assert_equal(q[0].text, "this") assert_equal(q[1].__class__, query.Term) assert_equal(q[1].text, "that") q = qp.parse("this&!that") assert_equal(q.__class__, query.AndNot) assert_equal(q.a.__class__, query.Term) assert_equal(q.a.text, "this") assert_equal(q.b.__class__, query.Term) assert_equal(q.b.text, "that") q = qp.parse("alfa -bravo NOT charlie") assert_equal(len(q), 4) assert_equal(q[1].__class__, query.Not) assert_equal(q[1].query.text, "bravo") assert_equal(q[2].text, "NOT")
def test_custom_tokens(): qp = qparser.QueryParser("text", None) qp.remove_plugin_class(plugins.OperatorsPlugin) cp = plugins.OperatorsPlugin(And="&", Or="\\|", AndNot="&!", AndMaybe="&~", Not="-") qp.add_plugin(cp) q = qp.parse("this | that") assert q.__class__ == query.Or assert q[0].__class__ == query.Term assert q[0].text == "this" assert q[1].__class__ == query.Term assert q[1].text == "that" q = qp.parse("this&!that") assert q.__class__ == query.AndNot assert q.a.__class__ == query.Term assert q.a.text == "this" assert q.b.__class__ == query.Term assert q.b.text == "that" q = qp.parse("alfa -bravo NOT charlie") assert len(q) == 4 assert q[1].__class__ == query.Not assert q[1].query.text == "bravo" assert q[2].text == "NOT"
def _query_parser_plugins(self): return [ plugins.WhitespacePlugin(), plugins.SingleQuotePlugin(), plugins.FieldsPlugin(), plugins.PrefixPlugin(), plugins.GroupPlugin(), plugins.OperatorsPlugin(), plugins.BoostPlugin()]
def default_set(self): """Returns the default list of plugins to use. """ from whoosh.qparser import plugins return [plugins.WhitespacePlugin(), plugins.SingleQuotePlugin(), plugins.FieldsPlugin(), plugins.WildcardPlugin(), plugins.PhrasePlugin(), plugins.RangePlugin(), plugins.GroupPlugin(), plugins.OperatorsPlugin(), plugins.BoostPlugin(), plugins.EveryPlugin(), ]
def test_groups_with_range(): p = default.QueryParser("t", None, [ plugins.FieldsPlugin(), plugins.GtLtPlugin(), plugins.GroupPlugin(), plugins.OperatorsPlugin(), plugins.PhrasePlugin(), plugins.RangePlugin(), plugins.RegexPlugin() ]) ns = p.process('a:b OR e:>=5 g:<6') assert repr( ns ) == "<AndGroup <OrGroup <'a':'b'>, <'e':['5' None]>>, <'g':[None '6'}>>" ns = p.process('a:b OR (e:>=5 g:<6)') assert repr( ns ) == "<AndGroup <OrGroup <'a':'b'>, <AndGroup <'e':['5' None]>, <'g':[None '6'}>>>>"
def test_operators(): p = default.QueryParser( "t", None, [plugins.WhitespacePlugin(), plugins.OperatorsPlugin()]) ns = p.process("a OR b") assert repr(ns) == "<AndGroup <OrGroup <None:'a'>, <None:'b'>>>"