Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
elasticsearch
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cubicweb
cubes
elasticsearch
Commits
4674c8a25531
Commit
4674c8a25531
authored
8 years ago
by
Arthur Lutz
Browse files
Options
Downloads
Patches
Plain Diff
[search_helpers] build composite searches (with tests)
parent
5a2f152284a8
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
search_helpers.py
+64
-0
64 additions, 0 deletions
search_helpers.py
test/test_compose_search.py
+75
-0
75 additions, 0 deletions
test/test_compose_search.py
with
139 additions
and
0 deletions
search_helpers.py
0 → 100644
+
64
−
0
View file @
4674c8a2
# -*- coding: utf-8 -*-
# copyright 2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
compiler.ast
import
flatten
from
elasticsearch_dsl
import
Q
def
compose_search
(
query
):
'''
Compose a elasticsearch-dsl query from queries :
* simple term
* simple terms (OR)
* negation (add - in front of a term)
* explicit OR
* quoted terms (AND)
'''
# FIXME TODO - restructure entier code base, have a proper lexer
must
=
[]
must_not
=
[]
should
=
[]
if
'"'
in
query
:
elements
=
flatten
([
x
.
split
()
for
x
in
query
.
split
(
'"'
)
if
x
])
elif
"'"
in
query
:
elements
=
flatten
([
x
.
split
()
for
x
in
query
.
split
(
"'"
)
if
x
])
else
:
elements
=
query
.
split
()
elements_lowercase
=
[
e
.
lower
()
for
e
in
elements
]
if
'
or
'
in
elements_lowercase
and
len
(
elements
)
>=
3
:
for
element
in
query
.
split
(
'
or
'
):
should
.
append
(
Q
(
'
multi_match
'
,
query
=
element
.
strip
(),
fields
=
()))
elements
=
[]
elif
'
-
'
not
in
query
:
elements
=
[
'
'
.
join
(
elements
)]
for
element
in
elements
:
if
element
.
startswith
(
'
-
'
):
must_not
.
append
(
Q
(
'
multi_match
'
,
query
=
element
[
1
:],
fields
=
()))
else
:
must
.
append
(
Q
(
'
multi_match
'
,
query
=
element
,
fields
=
()))
return
Q
(
'
bool
'
,
must
=
must
,
must_not
=
must_not
,
should
=
should
)
This diff is collapsed.
Click to expand it.
test/test_compose_search.py
0 → 100644
+
75
−
0
View file @
4674c8a2
# copyright 2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import
unittest
from
elasticsearch_dsl
import
Q
from
cubicweb.devtools
import
testlib
from
cubes.elasticsearch.search_helpers
import
compose_search
class
ComposeSearchTestCase
(
testlib
.
TestCase
):
def
test_simple
(
self
):
self
.
assertEquals
(
compose_search
(
'
test
'
),
Q
(
'
bool
'
,
must
=
[
Q
(
'
multi_match
'
,
query
=
'
test
'
,
fields
=
())]))
def
test_two_terms
(
self
):
self
.
assertEquals
(
compose_search
(
'
test this
'
),
Q
(
'
bool
'
,
must
=
[
Q
(
'
multi_match
'
,
query
=
'
test this
'
,
fields
=
())]))
def
test_two_with_quotes
(
self
):
self
.
assertEquals
(
compose_search
(
'"
test this
"'
),
Q
(
'
bool
'
,
must
=
[
Q
(
'
multi_match
'
,
query
=
'
test
'
,
fields
=
()),
Q
(
'
multi_match
'
,
query
=
'
this
'
,
fields
=
())]))
self
.
assertEquals
(
compose_search
(
"'
test this
'"
),
Q
(
'
bool
'
,
must
=
[
Q
(
'
multi_match
'
,
query
=
'
test
'
,
fields
=
()),
Q
(
'
multi_match
'
,
query
=
'
this
'
,
fields
=
())]))
# def test_three_with_quotes(self):
# self.assertEquals(compose_search('"test this" this_too'),
# Q('bool',
# must=[Q('multi_match', query='test', fields=()),
# Q('multi_match', query='this', fields=())],
# should=))
def
test_two_with_negate
(
self
):
self
.
assertEquals
(
compose_search
(
'
test -this
'
),
Q
(
'
bool
'
,
must
=
[
Q
(
'
multi_match
'
,
query
=
'
test
'
,
fields
=
())],
must_not
=
[
Q
(
'
multi_match
'
,
query
=
'
this
'
,
fields
=
())]))
def
test_two_with_or
(
self
):
self
.
assertEquals
(
compose_search
(
'
test or this
'
),
Q
(
'
bool
'
,
should
=
[
Q
(
'
multi_match
'
,
query
=
'
test
'
,
fields
=
()),
Q
(
'
multi_match
'
,
query
=
'
this
'
,
fields
=
())]))
# self.assertEquals(compose_search('test ou this'),
# Q('bool',
# should=[Q('multi_match', query='test', fields=()),
# Q('multi_match', query='this', fields=())]))
def
test_or_on_its_own
(
self
):
self
.
assertEquals
(
compose_search
(
'
or
'
),
Q
(
'
bool
'
,
must
=
[
Q
(
'
multi_match
'
,
query
=
'
or
'
,
fields
=
())]))
if
__name__
==
'
__main__
'
:
unittest
.
main
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment