5.4.2. OpenSearch

Die Anwendung brauchte eine Datenbank, um die Barcodes mit ihren Namen und Beschreibungen abzuspeichern. Als Ersatz für eine relationale Datenbank wurde Opensearch verwendet. Opensearch ist eine Open-Source-Such- und Analysesuite. In dieser Suite lassen sich Dateneinträge unter Indexen sammeln. Diese Datensammlungen lassen sich wiederum nach einzelnen Dateneinträgen über deren Datenfelder durchsuchen. Damit kann Opensearch auch als Datenbankalternative verwendet werden.

Für den Aufbau auf einem Server kann Opensearch einfach in einem Dockercontainer mit dem Befehl “ docker run -d -p 9200:9200 -p 9600:9600 -e “discovery.type=single-node” opensearchproject/opensearch:latest“ gestarted werden. Das Skript opensearch_test.py sollte zum Testen der lokalen Opensearch Instanz und zum initialisieren der Instanz einmal gestartet werden.

Die Kommunikation mit der Opensearch Instanz funktioniert über eine Python Schnittstelle. Diese Schnittstelle nutzt einen von Opensearch zur Verfügung gestellten Python Client, der die Kommunikation mit der Opensearch Instanz über eine RestAPI übernimmt.

Die Schnittstelle stellt unserer RestAPI über die Klasse “Opensearch_Client” zwei Funktionen zur Verfügung.

class Opensearch_Client ():
    def __init__(self) -> None:
        host = 'localhost'
        port = 9200
        auth = ('admin', 'admin')

        # Create the client with SSL/TLS enabled, but hostname verification disabled.
        self.client = OpenSearch(
            hosts = [{'host': host, 'port': port}],
            http_compress = True, # enables gzip compression for request bodies
            http_auth = auth,
            # client_cert = client_cert_path,
            # client_key = client_key_path,
            use_ssl = True,
            verify_certs = False,
            ssl_assert_hostname = False,
            ssl_show_warn = False,
            #ca_certs = ca_certs_path
        )

Die Funktion “search_barcode” ist bestimmt für das Suchen nach bestehenden Einträgen. Dafür wird ihr als Parameter der gesuchte Barcode als String übergeben. Die Datensammlung wird nach einem Eintrag mit dieser Id durchsucht. Bei Erfolg werden die im Eintrag gespeicherten Werte “name” und “description” zurückgegeben. Sowohl bei Erfolg wie auch Misserfolg wird dieser mit einem entsprechenden Wahrheitswert deutlich gemacht, der im Rückgabewert enthalten ist.

    def search_barcode(self, barcode: str):
        index_name = 'barcode'
        query ={
            'query':{
                'match': {
                    '_id':barcode
                },
            }
        }
        response = self.client.search(body = query, index = index_name)
        try:
            barcode_object = response['hits']['hits'][0]
            return (True,barcode_object['_source']['name'], barcode_object['_source']['description'])
        except (IndexError, KeyError) as e:
            print(e)
            return (False, "", "")

Die Funktion “upload_barcode” ist bestimmt für das Hinzufügen neuer Einträge in die Datensammlung. Dafür werden ihr als Parameter die Werte des Eintrags übergeben, der Barcode selbst als Identifizierer, der Name der dem Barcode zugeordnet werden solle und die Beschreibung die ihm zugeordnet werden soll. Der Eintrag wird der Datensammlung entsprechend der Paramteter hinzugefügt und gemäß des Erfolgs ein Wahrheitswert zurückgegeben. Dabei sollte beachtet werden, dass sollte versucht werden einen Eintrag hinzuzufügen der denselben Identifizierer wie ein bestehender hat, die Werte des bestehenden Überschrieben werden.

    def upload_barcode(self,barcode:str,name:str,description:str):
        barcode_data ={
            'barcode':barcode,
            'name':name,
            'description':description
        }
        try:
            self.client.index(
                index='barcode',
                body=barcode_data,
                id= barcode,
                refresh=True,
            )
            return True
        except:
            return False

Das speichern und suchen nach Einträgen findet unter dem Index “barcode” statt, um die Datensammlung abzugrenzen.