mongodb.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. """MongoDB_ is a document based database program that handles JSON like data.
  3. Before configuring the ``mongodb`` engine, you must install the dependency
  4. pymongo_.
  5. Configuration
  6. =============
  7. In order to query MongoDB_, you have to select a ``database`` and a
  8. ``collection``. Furthermore, you have to select a ``key`` that is going to be
  9. searched. MongoDB_ also supports the option ``exact_match_only``, so configure
  10. it as you wish.
  11. Example
  12. =======
  13. Below is an example configuration for using a MongoDB collection:
  14. .. code:: yaml
  15. # MongoDB engine
  16. # Required dependency: pymongo
  17. - name: mymongo
  18. engine: mongodb
  19. shortcut: md
  20. exact_match_only: false
  21. host: '127.0.0.1'
  22. port: 27017
  23. enable_http: true
  24. results_per_page: 20
  25. database: 'business'
  26. collection: 'reviews' # name of the db collection
  27. key: 'name' # key in the collection to search for
  28. Implementations
  29. ===============
  30. """
  31. from __future__ import annotations
  32. import re
  33. try:
  34. from pymongo import MongoClient # type: ignore
  35. except ImportError:
  36. # import error is ignored because the admin has to install pymongo manually
  37. # to use the engine
  38. pass
  39. from searx.result_types import EngineResults
  40. engine_type = 'offline'
  41. # mongodb connection variables
  42. host = '127.0.0.1'
  43. port = 27017
  44. username = ''
  45. password = ''
  46. database = None
  47. collection = None
  48. key = None
  49. # engine specific variables
  50. paging = True
  51. results_per_page = 20
  52. exact_match_only = False
  53. _client = None
  54. def init(_):
  55. connect()
  56. def connect():
  57. global _client # pylint: disable=global-statement
  58. kwargs: dict[str, str | int] = {'port': port}
  59. if username:
  60. kwargs['username'] = username
  61. if password:
  62. kwargs['password'] = password
  63. _client = MongoClient(host, **kwargs)[database][collection]
  64. def search(query, params) -> EngineResults:
  65. res = EngineResults()
  66. if exact_match_only:
  67. q = {'$eq': query}
  68. else:
  69. _re = re.compile('.*{0}.*'.format(re.escape(query)), re.I | re.M)
  70. q = {'$regex': _re}
  71. query = _client.find({key: q}).skip((params['pageno'] - 1) * results_per_page).limit(results_per_page)
  72. res.add(res.types.LegacyResult(number_of_results=query.count()))
  73. for row in query:
  74. del row['_id']
  75. kvmap = {str(k): str(v) for k, v in row.items()}
  76. res.add(res.types.KeyValue(kvmap=kvmap))
  77. return res