elasticsearch.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. from json import loads, dumps
  2. from lxml import html
  3. from urllib.parse import quote, urljoin
  4. from requests.auth import HTTPBasicAuth
  5. from searx.utils import extract_text, get_torrent_size
  6. base_url = 'http://localhost:9200'
  7. username = ''
  8. password = ''
  9. index = ''
  10. search_url = base_url + '/' + index + '/_search'
  11. query_type = 'match'
  12. custom_query_json = {}
  13. show_metadata = False
  14. categories = ['general']
  15. def init(engine_settings):
  16. if 'query_type' in engine_settings and engine_settings['query_type'] not in _available_query_types:
  17. raise ValueError('unsupported query type', engine_settings['query_type'])
  18. if index == '':
  19. raise ValueError('index cannot be empty')
  20. def request(query, params):
  21. if query_type not in _available_query_types:
  22. return params
  23. if username and password:
  24. params['auth'] = HTTPBasicAuth(username, password)
  25. params['url'] = search_url
  26. params['method'] = 'GET'
  27. params['data'] = dumps(_available_query_types[query_type](query))
  28. params['headers']['Content-Type'] = 'application/json'
  29. return params
  30. def _match_query(query):
  31. """
  32. The standard for full text queries.
  33. searx format: "key:value" e.g. city:berlin
  34. REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
  35. """
  36. try:
  37. key, value = query.split(':')
  38. except:
  39. raise ValueError('query format must be "key:value"')
  40. return {"query": {"match": {key: {'query': value}}}}
  41. def _simple_query_string_query(query):
  42. """
  43. Accepts query strings, but it is less strict than query_string
  44. The field used can be specified in index.query.default_field in Elasticsearch.
  45. REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html
  46. """
  47. return {'query': {'simple_query_string': {'query': query}}}
  48. def _term_query(query):
  49. """
  50. Accepts one term and the name of the field.
  51. searx format: "key:value" e.g. city:berlin
  52. REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
  53. """
  54. try:
  55. key, value = query.split(':')
  56. except:
  57. raise ValueError('query format must be key:value')
  58. return {'query': {'term': {key: value}}}
  59. def _terms_query(query):
  60. """
  61. Accepts multiple terms and the name of the field.
  62. searx format: "key:value1,value2" e.g. city:berlin,paris
  63. REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
  64. """
  65. try:
  66. key, values = query.split(':')
  67. except:
  68. raise ValueError('query format must be key:value1,value2')
  69. return {'query': {'terms': {key: values.split(',')}}}
  70. def _custom_query(query):
  71. key, value = query.split(':')
  72. custom_query = custom_query_json
  73. for query_key, query_value in custom_query.items():
  74. if query_key == '{{KEY}}':
  75. custom_query[key] = custom_query.pop(query_key)
  76. if query_value == '{{VALUE}}':
  77. custom_query[query_key] = value
  78. return custom_query
  79. def response(resp):
  80. results = []
  81. resp_json = loads(resp.text)
  82. if 'error' in resp_json:
  83. raise Exception(resp_json['error'])
  84. for result in resp_json['hits']['hits']:
  85. r = {key: str(value) if not key.startswith('_') else value for key, value in result['_source'].items()}
  86. r['template'] = 'key-value.html'
  87. if show_metadata:
  88. r['metadata'] = {'index': result['_index'],
  89. 'id': result['_id'],
  90. 'score': result['_score']}
  91. results.append(r)
  92. return results
  93. _available_query_types = {
  94. # Full text queries
  95. # https://www.elastic.co/guide/en/elasticsearch/reference/current/full-text-queries.html
  96. 'match': _match_query,
  97. 'simple_query_string': _simple_query_string_query,
  98. # Term-level queries
  99. # https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html
  100. 'term': _term_query,
  101. 'terms': _terms_query,
  102. # Query JSON defined by the instance administrator.
  103. 'custom': _custom_query,
  104. }