# Buggy code
def query_by_embedding(
    self,
    query_emb: np.array,
    filters: Optional[Dict[str, List[str]]] = None,
    top_k: int = 10,
    index: Optional[str] = None,
) -> List[Document]:
    if index is None:
        index = self.index

    if not self.embedding_field:
        raise RuntimeError(
            "Please specify arg `embedding_field` in ElasticsearchDocumentStore()"
        )
    else:
        # +1 in similarity to avoid negative numbers (for cosine sim)
        body = {
            "size": top_k,
            "query": {
                "script_score": {
                    "query": {"match_all": {}},
                    "script": {
                        "source": f"{self.similarity_fn_name}(params.query_vector,'{self.embedding_field}') + 1.0",
                        "params": {"query_vector": query_emb.tolist()},
                    },
                }
            },
        }  # type: Dict[str,Any]

        if filters:
            for key, values in filters.items():
                if type(values) != list:
                    raise ValueError(
                        f'Wrong filter format for key "{key}": Please provide a list of allowed values for each key. '
                        'Example: {"name": ["some", "more"], "category": ["only_one"]} '
                    )
            body["query"]["script_score"]["query"] = {"terms": filters}

        if self.excluded_meta_data:
            body["_source"] = {"excludes": self.excluded_meta_data}

        logger.debug(f"Retriever query: {body}")
        result = self.client.search(index=index, body=body, request_timeout=300)[
            "hits"
        ]["hits"]

        documents = [
            self._convert_es_hit_to_document(hit, adapt_score_for_embedding=True)
            for hit in result
        ]
        return documents


# Traceback (elasticsearch.exceptions.RequestError)
10/13/2020 06:43:06 - WARNING - elasticsearch -   POST http://localhost:9200/faq/_search [status:400 request:0.130s]
Traceback (most recent call last):
File "chatbots/haystack/faqbot.py", line 214, in <module>
main()
File "chatbots/haystack/faqbot.py", line 186, in main
faqbot.interact(question)
File "chatbots/haystack/faqbot.py", line 57, in interact
prediction = finder.get_answers_via_similar_questions(question=question, top_k_retriever=1)
File "/Users/aaronbriel/chatbots/haystack/.venv/src/farm-haystack/haystack/finder.py", line 95, in get_answers_via_similar_questions
documents = self.retriever.retrieve(question, top_k=top_k_retriever, filters=filters, index=index)
File "/Users/aaronbriel/chatbots/haystack/.venv/src/farm-haystack/haystack/retriever/dense.py", line 327, in retrieve
top_k=top_k, index=index)
File "/Users/aaronbriel/chatbots/haystack/.venv/src/farm-haystack/haystack/document_store/elasticsearch.py", line 465, in query_by_embedding
result = self.client.search(index=index, body=body, request_timeout=300)["hits"]["hits"]
File "/Users/aaronbriel/chatbots/haystack/.venv/lib/python3.7/site-packages/elasticsearch/client/utils.py", line 152, in _wrapped
return func(*args, params=params, headers=headers, **kwargs)
File "/Users/aaronbriel/chatbots/haystack/.venv/lib/python3.7/site-packages/elasticsearch/client/__init__.py", line 1617, in search
body=body,
File "/Users/aaronbriel/chatbots/haystack/.venv/lib/python3.7/site-packages/elasticsearch/transport.py", line 392, in perform_request
raise e
File "/Users/aaronbriel/chatbots/haystack/.venv/lib/python3.7/site-packages/elasticsearch/transport.py", line 365, in perform_request
timeout=timeout,
File "/Users/aaronbriel/chatbots/haystack/.venv/lib/python3.7/site-packages/elasticsearch/connection/http_urllib3.py", line 269, in perform_request
self._raise_error(response.status, raw_data)
File "/Users/aaronbriel/chatbots/haystack/.venv/lib/python3.7/site-packages/elasticsearch/connection/base.py", line 301, in _raise_error
status_code, error_message, additional_info
elasticsearch.exceptions.RequestError: RequestError(400, 'search_phase_execution_exception', 'script_score script returned an invalid score [-3.4487913] for doc [41]. Must be a non-negative score!')
make: *** [ask_faq] Error 1

# Fixed code
def query_by_embedding(
    self,
    query_emb: np.array,
    filters: Optional[Dict[str, List[str]]] = None,
    top_k: int = 10,
    index: Optional[str] = None,
) -> List[Document]:
    if index is None:
        index = self.index

    if not self.embedding_field:
        raise RuntimeError(
            "Please specify arg `embedding_field` in ElasticsearchDocumentStore()"
        )
    else:
        # +1 in similarity to avoid negative numbers (for cosine sim)
        body = {
            "size": top_k,
            "query": {
                "script_score": {
                    "query": {"match_all": {}},
                    "script": {
                        # offset score to ensure a positive range as required by Elasticsearch
                        "source": f"{self.similarity_fn_name}(params.query_vector,'{self.embedding_field}') + 1000",
                        "params": {"query_vector": query_emb.tolist()},
                    },
                }
            },
        }  # type: Dict[str,Any]

        if filters:
            for key, values in filters.items():
                if type(values) != list:
                    raise ValueError(
                        f'Wrong filter format for key "{key}": Please provide a list of allowed values for each key. '
                        'Example: {"name": ["some", "more"], "category": ["only_one"]} '
                    )
            body["query"]["script_score"]["query"] = {"terms": filters}

        if self.excluded_meta_data:
            body["_source"] = {"excludes": self.excluded_meta_data}

        logger.debug(f"Retriever query: {body}")
        result = self.client.search(index=index, body=body, request_timeout=300)[
            "hits"
        ]["hits"]

        documents = [
            self._convert_es_hit_to_document(hit, adapt_score_for_embedding=True)
            for hit in result
        ]
        return documents