Skip to content

Commit

Permalink
Support multi_match query type (#41)
Browse files Browse the repository at this point in the history
* Support multi_match queries
  • Loading branch information
emptyflash authored and alexgarel committed Aug 1, 2019
1 parent 1d1b9eb commit 73cbec0
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 11 deletions.
2 changes: 1 addition & 1 deletion luqum/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-

__version__ = '0.7.5'
__version__ = '0.8.0'
__version_info__ = tuple(__version__.split('.'))
12 changes: 8 additions & 4 deletions luqum/elasticsearch/tree.py
Expand Up @@ -38,8 +38,10 @@ def __init__(self, no_analyze=None, method='term', fields=[], _name=None, field_
def json(self):
field = self.field
inner_json = dict(self.field_options.get(field, {}))
inner_json.pop('type', None) # remove "type" key
if self.method == 'query_string':
result = inner_json.pop('match_type', None) # remove "match_type" key
if not result: # conditionally remove "type" (for backward compatibility)
inner_json.pop('type', None)
if self.method in ['query_string', 'multi_match']:
json = {self.method: inner_json}
else:
json = {self.method: {field: inner_json}}
Expand All @@ -50,7 +52,7 @@ def json(self):
value = getattr(self, key, None)
if value is not None:
if key == 'q':
if self.method.startswith('match'):
if 'match' in self.method:
inner_json['query'] = value
if self.method == 'match':
inner_json['zero_terms_query'] = self.zero_terms_query
Expand Down Expand Up @@ -94,7 +96,9 @@ def method(self):
if self._value_has_wildcard_char():
return 'query_string'
elif self._method.startswith("match"):
return self.field_options.get(self.field, {}).get("type", self._method)
options = self.field_options.get(self.field, {})
# Support the type opiton for backward compatibility
return options.get("match_type", options.get("type", self._method))
return self._method


Expand Down
2 changes: 1 addition & 1 deletion luqum/elasticsearch/visitor.py
Expand Up @@ -79,7 +79,7 @@ def __init__(self, default_operator=SHOULD, default_field='text',
None, will accept all non nested fields or object fields as sub fields.
:param dict field_options: allows you to give defaults options for each fields.
They will be applied unless, overwritten by generated parameters.
For match query, the `type` parameter modifies the query type.
For match query, the `match_type` parameter modifies the type of match query.
:param bool match_word_as_phrase: if True,
word expressions are matched using `match_phrase` instead of `match`.
This options mainly keeps stability with 0.6 version.
Expand Down
28 changes: 23 additions & 5 deletions luqum/tests/test_es_integration.py
Expand Up @@ -4,7 +4,7 @@
import elasticsearch_dsl
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
from elasticsearch_dsl import Date, Index, Integer, Nested, Object, Search
from elasticsearch_dsl import Date, Index, Integer, Nested, Object, Search, analyzer
from elasticsearch_dsl.connections import connections
from luqum.elasticsearch import ElasticsearchQueryBuilder, SchemaAnalyzer
from luqum.parser import parser
Expand Down Expand Up @@ -37,7 +37,12 @@ class Illustrator(InnerDoc):


class Book(Document):
title = Text()
title = Text(fields={
"no_vowels": Text(
analyzer=analyzer("no_vowels", "pattern", pattern="[\Waeiouy]"),
search_analyzer="standard"
)
})
edition = Text()
author = Object(properties={"name": Text(), "birthdate": Date()})
publication_date = Date()
Expand Down Expand Up @@ -88,9 +93,16 @@ def setUpClass(cls):
cls.search = Search(using=client, index="bk")
MESSAGES_SCHEMA = {"mappings": Book._doc_type.mapping.to_dict()}
schema_analizer = SchemaAnalyzer(MESSAGES_SCHEMA)
cls.es_builder = ElasticsearchQueryBuilder(
**schema_analizer.query_builder_options()
)

builder_options = schema_analizer.query_builder_options()
builder_options['field_options'] = {
'title.no_vowels': {
'match_type': 'multi_match',
'type': 'most_fields',
'fields': ('title', 'title.no_vowels')
}
}
cls.es_builder = ElasticsearchQueryBuilder(**builder_options)
add_data()

def _ask_luqum(self, req):
Expand Down Expand Up @@ -214,6 +226,12 @@ def test_complex_search(self):
["Harry Potter and the Order of the Phoenix"],
)

def test_subfield_multi_match_search(self):
self.assertListEqual(
self._ask_luqum("title.no_vowels:Potter AND title.no_vowels:x"),
["Harry Potter and the Order of the Phoenix"],
)

@classmethod
def tearDownClass(cls):
if ES6:
Expand Down

0 comments on commit 73cbec0

Please sign in to comment.