inspire-query-parser 0.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- inspire_query_parser/__init__.py +27 -0
- inspire_query_parser/ast.py +221 -0
- inspire_query_parser/config.py +238 -0
- inspire_query_parser/parser.py +1060 -0
- inspire_query_parser/parsing_driver.py +132 -0
- inspire_query_parser/stateful_pypeg_parser.py +50 -0
- inspire_query_parser/utils/__init__.py +21 -0
- inspire_query_parser/utils/format_parse_tree.py +115 -0
- inspire_query_parser/utils/visitor_utils.py +529 -0
- inspire_query_parser/visitors/__init__.py +21 -0
- inspire_query_parser/visitors/elastic_search_visitor.py +1027 -0
- inspire_query_parser/visitors/restructuring_visitor.py +419 -0
- inspire_query_parser/visitors/visitor_impl.py +42 -0
- inspire_query_parser-0.0.0.dist-info/LICENSE +674 -0
- inspire_query_parser-0.0.0.dist-info/METADATA +68 -0
- inspire_query_parser-0.0.0.dist-info/RECORD +18 -0
- inspire_query_parser-0.0.0.dist-info/WHEEL +6 -0
- inspire_query_parser-0.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# This file is part of INSPIRE.
|
|
4
|
+
# Copyright (C) 2014-2017 CERN.
|
|
5
|
+
#
|
|
6
|
+
# INSPIRE is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# INSPIRE is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with INSPIRE. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
#
|
|
19
|
+
# In applying this license, CERN does not waive the privileges and immunities
|
|
20
|
+
# granted to it by virtue of its status as an Intergovernmental Organization
|
|
21
|
+
# or submit itself to any jurisdiction.
|
|
22
|
+
"""A PEG-based query parser for INSPIRE."""
|
|
23
|
+
|
|
24
|
+
from __future__ import absolute_import, print_function
|
|
25
|
+
|
|
26
|
+
from inspire_query_parser import config # noqa: F401
|
|
27
|
+
from inspire_query_parser.parsing_driver import parse_query # noqa: F401
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# This file is part of INSPIRE.
|
|
4
|
+
# Copyright (C) 2014-2017 CERN.
|
|
5
|
+
#
|
|
6
|
+
# INSPIRE is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# INSPIRE is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with INSPIRE. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
#
|
|
19
|
+
# In applying this license, CERN does not waive the privileges and immunities
|
|
20
|
+
# granted to it by virtue of its status as an Intergovernmental Organization
|
|
21
|
+
# or submit itself to any jurisdiction.
|
|
22
|
+
"""AbstractSyntaxTree classes along with their concrete ones.
|
|
23
|
+
|
|
24
|
+
The module defines a generic AST element along with four AST node
|
|
25
|
+
categories (which act as a basis for all the concrete AST nodes) and
|
|
26
|
+
finally, the concrete classes which represent the output of the parsing
|
|
27
|
+
process.
|
|
28
|
+
|
|
29
|
+
The generic AST node categories are: - Leaf - UnaryOp -
|
|
30
|
+
BinaryOp - ListOp
|
|
31
|
+
|
|
32
|
+
The concrete AST nodes, represent higher level (domain specific) nodes.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from __future__ import unicode_literals
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# #### Abstract Syntax Tree classes ####
|
|
39
|
+
class ASTElement(object):
|
|
40
|
+
"""Root AbstractSyntaxTree node that acts as a stub for calling the
|
|
41
|
+
Visitor's `visit` dispatcher method."""
|
|
42
|
+
|
|
43
|
+
def accept(self, visitor, *args, **kwargs):
|
|
44
|
+
return visitor.visit(self, *args, **kwargs)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Leaf(ASTElement):
|
|
48
|
+
def __init__(self, value=None):
|
|
49
|
+
self.value = value
|
|
50
|
+
|
|
51
|
+
def __eq__(self, other):
|
|
52
|
+
return type(self) is type(other) and self.value == other.value
|
|
53
|
+
|
|
54
|
+
def __repr__(self):
|
|
55
|
+
return '%s(%r)' % (self.__class__.__name__, self.value)
|
|
56
|
+
|
|
57
|
+
def __hash__(self):
|
|
58
|
+
return hash(self.value)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class UnaryOp(ASTElement):
|
|
62
|
+
def __init__(self, op):
|
|
63
|
+
self.op = op
|
|
64
|
+
|
|
65
|
+
def __eq__(self, other):
|
|
66
|
+
return type(self) is type(other) and self.op == other.op
|
|
67
|
+
|
|
68
|
+
def __repr__(self):
|
|
69
|
+
return "%s(%r)" % (self.__class__.__name__, self.op)
|
|
70
|
+
|
|
71
|
+
def __hash__(self):
|
|
72
|
+
return hash(self.op)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class BinaryOp(ASTElement):
|
|
76
|
+
def __init__(self, left, right):
|
|
77
|
+
self.left = left
|
|
78
|
+
self.right = right
|
|
79
|
+
|
|
80
|
+
def __eq__(self, other):
|
|
81
|
+
return (
|
|
82
|
+
(type(self) is type(other))
|
|
83
|
+
and (self.left == other.left)
|
|
84
|
+
and (self.right == other.right)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def __repr__(self):
|
|
88
|
+
return "%s(%s, %s)" % (
|
|
89
|
+
self.__class__.__name__,
|
|
90
|
+
repr(self.left),
|
|
91
|
+
repr(self.right),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def __hash__(self):
|
|
95
|
+
return hash((self.left, self.right))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class ListOp(ASTElement):
|
|
99
|
+
def __init__(self, children):
|
|
100
|
+
try:
|
|
101
|
+
iter(children)
|
|
102
|
+
except TypeError:
|
|
103
|
+
self.children = [children]
|
|
104
|
+
else:
|
|
105
|
+
self.children = children
|
|
106
|
+
|
|
107
|
+
def __eq__(self, other):
|
|
108
|
+
return type(self) is type(other) and self.children == other.children
|
|
109
|
+
|
|
110
|
+
def __repr__(self):
|
|
111
|
+
return "%s(%r)" % (self.__class__.__name__, self.children)
|
|
112
|
+
|
|
113
|
+
def __hash__(self):
|
|
114
|
+
return hash(tuple(self.children))
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# Concrete Syntax Tree classes
|
|
118
|
+
class AndOp(BinaryOp):
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class OrOp(BinaryOp):
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class KeywordOp(BinaryOp):
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class NotOp(UnaryOp):
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class NestedKeywordOp(BinaryOp):
|
|
135
|
+
pass
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class ValueOp(UnaryOp):
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class QueryWithMalformedPart(BinaryOp):
|
|
143
|
+
"""A combination of recognized part of a query (with a parse tree) and some
|
|
144
|
+
malformed input.
|
|
145
|
+
|
|
146
|
+
Its left child is the recognized parse tree, while its right child
|
|
147
|
+
has the :class:`MalformedQuery`.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
pass
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class MalformedQuery(ListOp):
|
|
154
|
+
"""A :class:`ListOp` with children the unrecognized words of the parser's
|
|
155
|
+
input."""
|
|
156
|
+
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class RangeOp(BinaryOp):
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class GreaterEqualThanOp(UnaryOp):
|
|
165
|
+
pass
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class GreaterThanOp(UnaryOp):
|
|
169
|
+
pass
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class LessThanOp(UnaryOp):
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class LessEqualThanOp(UnaryOp):
|
|
177
|
+
pass
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# #### Leafs ####
|
|
181
|
+
class Keyword(Leaf):
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class GenericValue(Leaf):
|
|
186
|
+
"""Represents a generic value, which might contain a wildcard."""
|
|
187
|
+
|
|
188
|
+
WILDCARD_TOKEN = '*'
|
|
189
|
+
|
|
190
|
+
def __init__(self, value, contains_wildcard=False):
|
|
191
|
+
super(GenericValue, self).__init__(value)
|
|
192
|
+
self.contains_wildcard = contains_wildcard
|
|
193
|
+
|
|
194
|
+
def __eq__(self, other):
|
|
195
|
+
return (
|
|
196
|
+
super(GenericValue, self).__eq__(other)
|
|
197
|
+
and self.contains_wildcard == other.contains_wildcard
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
def __hash__(self):
|
|
201
|
+
return hash((super(GenericValue, self).__hash__(), self.contains_wildcard))
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class Value(GenericValue):
|
|
205
|
+
pass
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class ExactMatchValue(Leaf):
|
|
209
|
+
pass
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class PartialMatchValue(GenericValue):
|
|
213
|
+
pass
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class RegexValue(Leaf):
|
|
217
|
+
pass
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class EmptyQuery(Leaf):
|
|
221
|
+
pass
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# This file is part of INSPIRE.
|
|
4
|
+
# Copyright (C) 2014-2017 CERN.
|
|
5
|
+
#
|
|
6
|
+
# INSPIRE is free software: you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
# (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# INSPIRE is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
# GNU General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU General Public License
|
|
17
|
+
# along with INSPIRE. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
#
|
|
19
|
+
# In applying this license, CERN does not waive the privileges and immunities
|
|
20
|
+
# granted to it by virtue of its status as an Intergovernmental Organization
|
|
21
|
+
# or submit itself to any jurisdiction.
|
|
22
|
+
"""A collection of INSPIRE related keywords.
|
|
23
|
+
|
|
24
|
+
This dictionary has a twofold use. Primarily, the parser uses its keys
|
|
25
|
+
to generate INSPIRE related keywords (i.e. qualifiers) and secondly,
|
|
26
|
+
provides a normalization of the shortened keywords to their full
|
|
27
|
+
version.
|
|
28
|
+
"""
|
|
29
|
+
from __future__ import unicode_literals
|
|
30
|
+
|
|
31
|
+
INSPIRE_PARSER_NONDATE_KEYWORDS = {
|
|
32
|
+
# Abstract
|
|
33
|
+
'abstract': 'abstract',
|
|
34
|
+
# Address
|
|
35
|
+
'address': 'address',
|
|
36
|
+
# Affiliation
|
|
37
|
+
'affiliation': 'affiliation',
|
|
38
|
+
'affil': 'affiliation',
|
|
39
|
+
'aff': 'affiliation',
|
|
40
|
+
'af': 'affiliation',
|
|
41
|
+
'institution': 'affiliation',
|
|
42
|
+
'inst': 'affiliation',
|
|
43
|
+
# Affiliation Id
|
|
44
|
+
'affid': 'affiliation-id',
|
|
45
|
+
'affiliation-id': 'affiliation-id',
|
|
46
|
+
# Author
|
|
47
|
+
'author': 'author',
|
|
48
|
+
'au': 'author',
|
|
49
|
+
'a': 'author',
|
|
50
|
+
'name': 'author',
|
|
51
|
+
# Author-Count
|
|
52
|
+
'author-count': 'author-count',
|
|
53
|
+
'authorcount': 'author-count',
|
|
54
|
+
'ac': 'author-count',
|
|
55
|
+
# Cataloguer
|
|
56
|
+
'cat': 'cataloguer',
|
|
57
|
+
# Caption
|
|
58
|
+
'caption': 'caption',
|
|
59
|
+
# Cite, i.e. records that cite the given search term
|
|
60
|
+
# Cite and c: SPIRES syntax while reference is INVENIO syntax
|
|
61
|
+
'cite': 'cite',
|
|
62
|
+
'c': 'cite',
|
|
63
|
+
'reference': 'cite',
|
|
64
|
+
# Citedby related
|
|
65
|
+
'citedby': 'citedby', # nested keyword query
|
|
66
|
+
# Cited by excluding self sites, e.g. citedbyexcludingselfcites:author:M.E.Peskin.1
|
|
67
|
+
'citedbyexcludingselfcites': 'citedbyexcludingselfcites',
|
|
68
|
+
'citedbyx': 'citedbyexcludingselfcites',
|
|
69
|
+
# Cited excluding self sites, e.g. citedexcludingselfcites:50+
|
|
70
|
+
'citedexcludingselfcites': 'citedexcludingselfcites',
|
|
71
|
+
'cx': 'citedexcludingselfcites',
|
|
72
|
+
# Collaboration
|
|
73
|
+
'collaboration': 'collaboration',
|
|
74
|
+
'cn': 'collaboration',
|
|
75
|
+
# Conference number
|
|
76
|
+
'cnum': 'confnumber',
|
|
77
|
+
# Control number
|
|
78
|
+
'control_number': 'control_number',
|
|
79
|
+
'recid': 'control_number',
|
|
80
|
+
# Country
|
|
81
|
+
'country': 'country',
|
|
82
|
+
'cc': 'country',
|
|
83
|
+
# DOI
|
|
84
|
+
'doi': 'doi',
|
|
85
|
+
# ePrint
|
|
86
|
+
'bb': 'eprint',
|
|
87
|
+
'bull': 'eprint',
|
|
88
|
+
'eprint': 'eprint',
|
|
89
|
+
'arxiv': 'eprint',
|
|
90
|
+
'arXiv': 'eprint',
|
|
91
|
+
# Exact-Author
|
|
92
|
+
'exact-author': 'exact-author',
|
|
93
|
+
'exactauthor': 'exact-author',
|
|
94
|
+
'ea': 'exact-author',
|
|
95
|
+
# Experiment
|
|
96
|
+
'experiment': 'experiment',
|
|
97
|
+
'exp': 'experiment',
|
|
98
|
+
# Field-code
|
|
99
|
+
'fc': 'field-code',
|
|
100
|
+
'field-code': 'field-code',
|
|
101
|
+
# First-Author
|
|
102
|
+
'first-author': 'first_author',
|
|
103
|
+
'firstauthor': 'first_author',
|
|
104
|
+
'fa': 'first_author',
|
|
105
|
+
# Fulltext
|
|
106
|
+
'fulltext': 'fulltext',
|
|
107
|
+
'ft': 'fulltext',
|
|
108
|
+
# SPIRES identifiers
|
|
109
|
+
'irn': 'irn',
|
|
110
|
+
# Journal related
|
|
111
|
+
'coden': 'journal',
|
|
112
|
+
'journal': 'journal',
|
|
113
|
+
'j': 'journal',
|
|
114
|
+
'published_in': 'journal',
|
|
115
|
+
'volume': 'volume',
|
|
116
|
+
'vol': 'volume',
|
|
117
|
+
# Keyword
|
|
118
|
+
# keyword is Invenio style, while the rest are from SPIRES syntax.
|
|
119
|
+
'keyword': 'keyword',
|
|
120
|
+
'keywords': 'keyword',
|
|
121
|
+
'kw': 'keyword',
|
|
122
|
+
'k': 'keyword',
|
|
123
|
+
# Primary archive
|
|
124
|
+
'primarch': 'primary_arxiv_category',
|
|
125
|
+
# rawref
|
|
126
|
+
'rawref': 'rawref',
|
|
127
|
+
# Reference
|
|
128
|
+
'citation': 'reference',
|
|
129
|
+
'jour-vol-page': 'reference',
|
|
130
|
+
'jvp': 'reference',
|
|
131
|
+
# Refersto operator
|
|
132
|
+
# Nested keyword query
|
|
133
|
+
'refersto': 'refersto',
|
|
134
|
+
# Refers to excluding self cites,
|
|
135
|
+
# e.g. referstoexcludingselfcites:author:M.E.Peskin.1
|
|
136
|
+
# Nested keyword queries
|
|
137
|
+
'referstoexcludingselfcites': 'referstoexcludingselfcites',
|
|
138
|
+
'referstox': 'referstoexcludingselfcites',
|
|
139
|
+
# Report number
|
|
140
|
+
'reportnumber': 'reportnumber',
|
|
141
|
+
'report-num': 'reportnumber',
|
|
142
|
+
'report': 'reportnumber',
|
|
143
|
+
'rept': 'reportnumber',
|
|
144
|
+
'rn': 'reportnumber',
|
|
145
|
+
'r': 'reportnumber',
|
|
146
|
+
# Subject
|
|
147
|
+
'subject': 'subject',
|
|
148
|
+
# Title
|
|
149
|
+
'title': 'title',
|
|
150
|
+
'ti': 'title',
|
|
151
|
+
't': 'title',
|
|
152
|
+
# texkey
|
|
153
|
+
'texkey': 'texkeys.raw',
|
|
154
|
+
# Topcite, i.e. citation count
|
|
155
|
+
# Cited used to be for Invenio style syntax while topcite for SPIRES
|
|
156
|
+
'cited': 'topcite',
|
|
157
|
+
'topcit': 'topcite',
|
|
158
|
+
'topcite': 'topcite',
|
|
159
|
+
# Type-Code
|
|
160
|
+
'type-code': 'type-code',
|
|
161
|
+
'type': 'type-code',
|
|
162
|
+
'tc': 'type-code',
|
|
163
|
+
'ty': 'type-code',
|
|
164
|
+
'scl': 'type-code',
|
|
165
|
+
'ps': 'type-code',
|
|
166
|
+
'collection': 'type-code',# Queries for this one include "collection published" only
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
INSPIRE_PARSER_DATE_KEYWORDS = {
|
|
170
|
+
# Date
|
|
171
|
+
'date': 'date',
|
|
172
|
+
'd': 'date',
|
|
173
|
+
# From queries dataset, users seem to use year and date interchangeably.
|
|
174
|
+
'year': 'date',
|
|
175
|
+
# Date added
|
|
176
|
+
'date-added': 'date-added',
|
|
177
|
+
'dadd': 'date-added',
|
|
178
|
+
'da': 'date-added',
|
|
179
|
+
# Date earliest
|
|
180
|
+
'date-earliest': 'date-earliest',
|
|
181
|
+
'de': 'date-earliest',
|
|
182
|
+
# Date updated
|
|
183
|
+
'date-updated': 'date-updated',
|
|
184
|
+
'dupd': 'date-updated',
|
|
185
|
+
'du': 'date-updated',
|
|
186
|
+
# Journal year
|
|
187
|
+
'journal-year': 'publication_info.year',
|
|
188
|
+
'jy': 'publication_info.year',
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
INSPIRE_PARSER_KEYWORDS = INSPIRE_PARSER_NONDATE_KEYWORDS.copy()
|
|
192
|
+
INSPIRE_PARSER_KEYWORDS.update(INSPIRE_PARSER_DATE_KEYWORDS)
|
|
193
|
+
INSPIRE_KEYWORDS_SET = set(INSPIRE_PARSER_KEYWORDS.values())
|
|
194
|
+
|
|
195
|
+
# #### Date specifiers #####
|
|
196
|
+
DATE_TODAY_REGEX_PATTERN = 'today'
|
|
197
|
+
DATE_YESTERDAY_REGEX_PATTERN = 'yesterday'
|
|
198
|
+
DATE_LAST_MONTH_REGEX_PATTERN = 'last\s+month'
|
|
199
|
+
DATE_THIS_MONTH_REGEX_PATTERN = 'this\s+month'
|
|
200
|
+
|
|
201
|
+
DATE_SPECIFIERS_COLLECTION = (
|
|
202
|
+
DATE_TODAY_REGEX_PATTERN,
|
|
203
|
+
DATE_YESTERDAY_REGEX_PATTERN,
|
|
204
|
+
DATE_THIS_MONTH_REGEX_PATTERN,
|
|
205
|
+
DATE_LAST_MONTH_REGEX_PATTERN,
|
|
206
|
+
)
|
|
207
|
+
MONTH_REGEX = "|".join(
|
|
208
|
+
[
|
|
209
|
+
"january",
|
|
210
|
+
"jan",
|
|
211
|
+
"february",
|
|
212
|
+
"feb",
|
|
213
|
+
"march",
|
|
214
|
+
"mar",
|
|
215
|
+
"april",
|
|
216
|
+
"apr",
|
|
217
|
+
"may",
|
|
218
|
+
"june",
|
|
219
|
+
'jun',
|
|
220
|
+
"july",
|
|
221
|
+
"jul",
|
|
222
|
+
"august",
|
|
223
|
+
"aug",
|
|
224
|
+
"september",
|
|
225
|
+
"sep",
|
|
226
|
+
"october",
|
|
227
|
+
"oct",
|
|
228
|
+
"november",
|
|
229
|
+
"nov",
|
|
230
|
+
"december",
|
|
231
|
+
"dec",
|
|
232
|
+
]
|
|
233
|
+
)
|
|
234
|
+
# #####
|
|
235
|
+
|
|
236
|
+
ES_MUST_QUERY = "must"
|
|
237
|
+
ES_SHOULD_QUERY = "should"
|
|
238
|
+
DEFAULT_ES_OPERATOR_FOR_MALFORMED_QUERIES = ES_MUST_QUERY
|