# SPDX-License-Identifier: AGPL-3.0-or-later """MongoDB_ is a document based database program that handles JSON like data. Before configuring the ``mongodb`` engine, you must install the dependency pymongo_. Configuration ============= In order to query MongoDB_, you have to select a ``database`` and a ``collection``. Furthermore, you have to select a ``key`` that is going to be searched. MongoDB_ also supports the option ``exact_match_only``, so configure it as you wish. Example ======= Below is an example configuration for using a MongoDB collection: .. code:: yaml # MongoDB engine # Required dependency: pymongo - name: mymongo engine: mongodb shortcut: md exact_match_only: false host: '127.0.0.1' port: 27017 enable_http: true results_per_page: 20 database: 'business' collection: 'reviews' # name of the db collection key: 'name' # key in the collection to search for Implementations =============== """ from __future__ import annotations import re try: from pymongo import MongoClient # type: ignore except ImportError: # import error is ignored because the admin has to install pymongo manually # to use the engine pass from searx.result_types import EngineResults engine_type = 'offline' # mongodb connection variables host = '127.0.0.1' port = 27017 username = '' password = '' database = None collection = None key = None # engine specific variables paging = True results_per_page = 20 exact_match_only = False _client = None def init(_): connect() def connect(): global _client # pylint: disable=global-statement kwargs: dict[str, str | int] = {'port': port} if username: kwargs['username'] = username if password: kwargs['password'] = password _client = MongoClient(host, **kwargs)[database][collection] def search(query, params) -> EngineResults: res = EngineResults() if exact_match_only: q = {'$eq': query} else: _re = re.compile('.*{0}.*'.format(re.escape(query)), re.I | re.M) q = {'$regex': _re} query = _client.find({key: q}).skip((params['pageno'] - 1) * results_per_page).limit(results_per_page) res.add(res.types.LegacyResult(number_of_results=query.count())) for row in query: del row['_id'] kvmap = {str(k): str(v) for k, v in row.items()} res.add(res.types.KeyValue(kvmap=kvmap)) return res