mirror of
				https://github.com/searxng/searxng
				synced 2024-01-01 19:24:07 +01:00 
			
		
		
		
	Fix elasticsearch custom_query.
This commit is contained in:
		
							parent
							
								
									f6f622f7e5
								
							
						
					
					
						commit
						bc5068fece
					
				
					 2 changed files with 147 additions and 6 deletions
				
			
		|  | @ -135,14 +135,38 @@ def _terms_query(query): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def _custom_query(query): | def _custom_query(query): | ||||||
|     key, value = query.split(':') |     key = value = None | ||||||
|     custom_query = custom_query_json |     if any(placeholder in custom_query_json for placeholder in ["{{KEY}}", "{{VALUE}}", "{{VALUES}}"]): | ||||||
|  |         try: | ||||||
|  |             key, value = query.split(':', maxsplit=1) | ||||||
|  |         except Exception as e: | ||||||
|  |             raise ValueError('query format must be "key:value"') from e | ||||||
|  |         if not key: | ||||||
|  |             raise ValueError('empty key from "key:value" query') | ||||||
|  |     try: | ||||||
|  |         custom_query = loads(custom_query_json) | ||||||
|  |     except Exception as e: | ||||||
|  |         raise ValueError('invalid custom_query string') from e | ||||||
|  |     return _custom_query_r(query, key, value, custom_query) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _custom_query_r(query, key, value, custom_query): | ||||||
|  |     new_query = {} | ||||||
|     for query_key, query_value in custom_query.items(): |     for query_key, query_value in custom_query.items(): | ||||||
|         if query_key == '{{KEY}}': |         if query_key == '{{KEY}}': | ||||||
|             custom_query[key] = custom_query.pop(query_key) |             query_key = key | ||||||
|         if query_value == '{{VALUE}}': | 
 | ||||||
|             custom_query[query_key] = value |         if isinstance(query_value, dict): | ||||||
|     return custom_query |             query_value = _custom_query_r(query, key, value, query_value) | ||||||
|  |         elif query_value == '{{VALUE}}': | ||||||
|  |             query_value = value | ||||||
|  |         elif query_value == '{{VALUES}}': | ||||||
|  |             query_value = value.split(',') | ||||||
|  |         elif query_value == '{{QUERY}}': | ||||||
|  |             query_value = query | ||||||
|  | 
 | ||||||
|  |         new_query[query_key] = query_value | ||||||
|  |     return new_query | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def response(resp): | def response(resp): | ||||||
|  |  | ||||||
							
								
								
									
										117
									
								
								tests/unit/engines/test_elasticsearch.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								tests/unit/engines/test_elasticsearch.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,117 @@ | ||||||
|  | # SPDX-License-Identifier: AGPL-3.0-or-later | ||||||
|  | # pylint: disable=missing-module-docstring | ||||||
|  | 
 | ||||||
|  | ''' | ||||||
|  | searx is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU Affero General Public License as published by | ||||||
|  | the Free Software Foundation, either version 3 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | searx 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 Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU Affero General Public License | ||||||
|  | along with searx. If not, see < http://www.gnu.org/licenses/ >. | ||||||
|  | 
 | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | from json import loads | ||||||
|  | from searx.engines import elasticsearch as elasticsearch_engine | ||||||
|  | from tests import SearxTestCase | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TestElasticsearchEngine(SearxTestCase):  # pylint: disable=missing-class-docstring | ||||||
|  |     default_params = {"headers": {}} | ||||||
|  | 
 | ||||||
|  |     def test_url_settings(self): | ||||||
|  |         elasticsearch_engine.base_url = 'http://es:12345' | ||||||
|  |         elasticsearch_engine.index = 'index' | ||||||
|  |         params = elasticsearch_engine.request("city:berlin", self.default_params) | ||||||
|  |         self.assertEqual(params["url"], "http://es:12345/index/_search") | ||||||
|  | 
 | ||||||
|  |     def test_basic_queries(self): | ||||||
|  |         queries = [ | ||||||
|  |             ['match', 'field:stuff', '{"query": {"match": {"field": {"query": "stuff"}}}}'], | ||||||
|  |             ['simple_query_string', 'stuff', '{"query": {"simple_query_string": {"query": "stuff"}}}'], | ||||||
|  |             ['term', 'field:stuff', '{"query": {"term": {"field": "stuff"}}}'], | ||||||
|  |             ['terms', 'field:stuff1,stuff2', '{"query": {"terms": {"field": ["stuff1", "stuff2"]}}}'], | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  |         for query in queries: | ||||||
|  |             elasticsearch_engine.query_type = query[0] | ||||||
|  |             params = elasticsearch_engine.request(query[1], self.default_params) | ||||||
|  |             self.assertEqual(loads(params["data"]), loads(query[2])) | ||||||
|  | 
 | ||||||
|  |     def test_basic_failures(self): | ||||||
|  |         queries = [ | ||||||
|  |             ['match', 'stuff'], | ||||||
|  |             ['term', 'stuff'], | ||||||
|  |             ['terms', 'stuff'], | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  |         for query in queries: | ||||||
|  |             elasticsearch_engine.query_type = query[0] | ||||||
|  |             self.assertRaises(ValueError, elasticsearch_engine.request, query[1], self.default_params) | ||||||
|  | 
 | ||||||
|  |     def test_custom_queries(self): | ||||||
|  |         queries = [ | ||||||
|  |             [ | ||||||
|  |                 'field:stuff', | ||||||
|  |                 '{"query": {"match": {"{{KEY}}": {"query": "{{VALUE}}"}}}}', | ||||||
|  |                 '{"query": {"match": {"field": {"query": "stuff"}}}}', | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'stuff', | ||||||
|  |                 '{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}', | ||||||
|  |                 '{"query": {"simple_query_string": {"query": "stuff"}}}', | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'more:stuff', | ||||||
|  |                 '{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}', | ||||||
|  |                 '{"query": {"simple_query_string": {"query": "more:stuff"}}}', | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'field:stuff', | ||||||
|  |                 '{"query": {"term": {"{{KEY}}": "{{VALUE}}"}}}', | ||||||
|  |                 '{"query": {"term": {"field": "stuff"}}}', | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'field:more:stuff', | ||||||
|  |                 '{"query": {"match": {"{{KEY}}": {"query": "{{VALUE}}"}}}}', | ||||||
|  |                 '{"query": {"match": {"field": {"query": "more:stuff"}}}}', | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'field:stuff1,stuff2', | ||||||
|  |                 '{"query": {"terms": {"{{KEY}}": "{{VALUES}}"}}}', | ||||||
|  |                 '{"query": {"terms": {"field": ["stuff1", "stuff2"]}}}', | ||||||
|  |             ], | ||||||
|  |             [ | ||||||
|  |                 'field:stuff1', | ||||||
|  |                 '{"query": {"terms": {"{{KEY}}": "{{VALUES}}"}}}', | ||||||
|  |                 '{"query": {"terms": {"field": ["stuff1"]}}}', | ||||||
|  |             ], | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  |         elasticsearch_engine.query_type = 'custom' | ||||||
|  |         for query in queries: | ||||||
|  |             elasticsearch_engine.custom_query_json = query[1] | ||||||
|  |             params = elasticsearch_engine.request(query[0], self.default_params) | ||||||
|  |             self.assertEqual(loads(params["data"]), loads(query[2])) | ||||||
|  | 
 | ||||||
|  |     def test_custom_failures(self): | ||||||
|  |         queries = [ | ||||||
|  |             ['stuff', '{"query": {"match": {"{{KEY}}": {"query": "{{VALUE}}"}}}}'], | ||||||
|  |             ['stuff', '{"query": {"terms": {"{{KEY}}": "{{VALUES}}"}}}'], | ||||||
|  |             ['stuff', '{"query": {"simple_query_string": {"query": {{QUERY}}}}}'], | ||||||
|  |             ['stuff', '"query": {"simple_query_string": {"query": "{{QUERY}}"}}}'], | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  |         elasticsearch_engine.query_type = 'custom' | ||||||
|  |         for query in queries: | ||||||
|  |             elasticsearch_engine.custom_query_json = query[1] | ||||||
|  |             self.assertRaises(ValueError, elasticsearch_engine.request, query[0], self.default_params) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # vi:sw=4 | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Richard Lyons
						Richard Lyons