# Exact-Knn with python api

**URL:** <https://discuss.elastic.co/t/exact-knn-with-python-api/365542>\
**Category:** Elasticsearch\
**Tags:** language-clients, vector-search\
**Created:** [August 26, 2024, 10:45am UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542 "2024-08-26T10:45:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![cazzz99](https://avatars.discourse-cdn.com/v4/letter/c/a88e4f/32.png) [@cazzz99](https://discuss.elastic.co/u/cazzz99)\
**Post date:** [August 26, 2024, 10:45am UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/1 "2024-08-26T10:45:13Z")

</div>

I've been using budy func + langchain retriever to conduct search in ES, my code is like below:

``

```
def embed_query(self,query_text,k =30,candidate_num = 45):
    if query_text is not None and len(query_text) == 0:
        print("query is empty")
        return None
    embedding_model,_ = self.embedding_model_local()
    query_vector = embedding_model.encode(query_text)
    return{
        "knn": {
            "field": "output_dense_vector",
            "query_vector": query_vector,
            "k": k,
            "num_candidates": candidate_num
        },
    }
    
async def async_es_A_KNN(self,query):
    es_retriever = ElasticsearchRetriever(
    index_name=self.index_name,
    body_func=self.embed_query,
    content_field="text",
    es_client = self.es_client,
)
    res =await es_retriever.ainvoke(query)
    retrived_docs = res
    # resp ={i.page_content: i.metadata["_score"] for i in retrived_docs}
    return {i.page_content: i.metadata["_score"] for i in retrived_docs}

```

and my mapping func is like this:

```
def create_index(self,text_field = "text",title_field = "title",dense_vector_field = "output_dense_vector",num_characters_field = "num_characters"):
    # es_client = connect_elasticsearch()
    self.es_client.indices.create(
        index=self.index_name,
        mappings={
            "properties": {
                #name the fields as given 
                text_field: {"type": "text"},
                title_field: {"type": "text"},
                dense_vector_field: {"type": "dense_vector"},
                num_characters_field: {"type": "integer"},
            }
        },
    )

```

``

I've been looked up the knn-search page but there's no python version template, hence can somebody tell me how can I perform exact knn with python api?

---

<div class="post-metadata">

**Author:** ![jessgarson](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jessgarson/32/129841_2.png) [@jessgarson](https://discuss.elastic.co/u/jessgarson)\
**Post date:** [August 26, 2024, 5:48pm UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/2 "2024-08-26T17:48:28Z")

</div>

Thanks, @cazzz99. We have an example of [exact KNN with Python in our docs.](https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html#exact-knn)Let me know if this helps or if you are looking for something different.

---

<div class="post-metadata">

**Author:** ![cazzz99](https://avatars.discourse-cdn.com/v4/letter/c/a88e4f/32.png) [@cazzz99](https://discuss.elastic.co/u/cazzz99)\
**Post date:** [August 27, 2024, 3:22am UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/3 "2024-08-27T03:22:21Z")

</div>

Thanks ! I've checked that out, yet I found the example is to search in a numeral field(price range as to the example). I wonder is it possible to search on a text field? Just like my code? If so, how should I edit the body func accordingly?

---

<div class="post-metadata">

**Author:** ![cazzz99](https://avatars.discourse-cdn.com/v4/letter/c/a88e4f/32.png) [@cazzz99](https://discuss.elastic.co/u/cazzz99)\
**Post date:** [August 27, 2024, 3:50am UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/4 "2024-08-27T03:50:33Z")

</div>

Referenced from the docs, I've tried out this:

```
def exact_knn(self,query_text):
    if query_text is not None and len(query_text) == 0:
        print("query is empty")
        return None
    embed_model,_ = self.embedding_model_local()
    query_vector = embed_model.encode(query_text)
    return {
        "query":{
            "script_score": {
        "query": {
          'match': {
              "text":query_text
          }
        },
        "script": {
            "source": "cosineSimilarity(params.queryVector, 'product-vector') + 1.0",
            "params": {
                "queryVector": query_vector
            }
        }
    }
        }
    }

```

when testing I received this：

```auto
   elasticsearch.BadRequestError: BadRequestError(400, 'search_phase_execution_exception', "class_cast_exception: class org.elasticsearch.script.field.EmptyField cannot be cast to class org.elasticsearch.script.field.vectors.DenseVectorDocValuesField (org.elasticsearch.script.field.EmptyField and org.elasticsearch.script.field.vectors.DenseVectorDocValuesField are in module org.elasticsearch.server@8.13.4 of loader 'app')") 

```

My mapping is quite simple :

```auto
self.es_client.indices.create(
            index=self.index_name,
            mappings={
                "properties": {
                    #name the fields as given 
                    text_field: {"type": "text"},
                    title_field: {"type": "text"},
                    dense_vector_field: {"type": "dense_vector"},
                    num_characters_field: {"type": "integer"},
                }
            },

```

Can somebody help me with this ?

---

<div class="post-metadata">

**Author:** ![jessgarson](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jessgarson/32/129841_2.png) [@jessgarson](https://discuss.elastic.co/u/jessgarson)\
**Post date:** [August 27, 2024, 2:16pm UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/5 "2024-08-27T14:16:37Z")

</div>

Thanks, @cazzz99. Do you have a complete code sample you can send over?

---

<div class="post-metadata">

**Author:** ![cazzz99](https://avatars.discourse-cdn.com/v4/letter/c/a88e4f/32.png) [@cazzz99](https://discuss.elastic.co/u/cazzz99)\
**Post date:** [August 28, 2024, 2:26am UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/6 "2024-08-28T02:26:04Z")

</div>

yea, so firstly my mapping for the index is:

```auto
    def create_index(self,text_field = "text",title_field = "title",dense_vector_field = "output_dense_vector",num_characters_field = "num_characters"):
        # es_client = connect_elasticsearch()
        self.es_client.indices.create(
            index=self.index_name,
            mappings={
                "properties":{
                    text_field: {"type": "text"},
                    title_field: {"type": "text"},
                    dense_vector_field: {"type": "dense_vector"},
                    num_characters_field: {"type": "integer"}
                }
            }
        )

```

and the method that I call exact search is like：

```auto
def exact_knn(self,query_text):
        if query_text is not None and len(query_text) == 0:
            print("query is empty")
            return None
        embed_model,_ = self.embedding_model_local()
        query_vector = embed_model.encode(query_text)
        return {
            "query":{
                "script_score": {
            "query": {
              'match': {
                  "text":query_text
              }
            },
            "script": {
                "source": "cosineSimilarity(params.queryVector, 'product-vector') + 1.0",
                "params": {
                    "queryVector": query_vector
                }
            }
        }
            }
        }

   
    def es_Exact_KNN(self,query):
        es_retriever = ElasticsearchRetriever(
        index_name=self.index_name,
        body_func=self.exact_knn,
        content_field="text",
        es_client = self.es_client,
    )
        res = es_retriever.invoke(query)
        return {i.page_content: i.metadata["_score"] for i in res}

```

---

<div class="post-metadata">

**Author:** ![jessgarson](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jessgarson/32/129841_2.png) [@jessgarson](https://discuss.elastic.co/u/jessgarson)\
**Post date:** [August 28, 2024, 5:14pm UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/7 "2024-08-28T17:14:17Z")

</div>

Thanks for all the follow up here. What version of Elastic are you using? Depending on your version you will want to make ensure that `query_vector` [contains floats and not doubles](https://www.elastic.co/guide/en/elasticsearch/reference/7.12/breaking-changes-7.4.html#_use_float_instead_of_double_for_query_vectors).

This post [about a similar issue](https://stackoverflow.com/questions/67313858/get-requesterror400-search-phase-execution-exception-runtime-error-for-c) may also be helpful here, as well as [this one](https://discuss.elastic.co/t/dense-vector-search-using-script-score/328375/2).

---

<div class="post-metadata">

**Author:** ![Justin\_Castilla](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/justin_castilla/32/135379_2.png) [@Justin\_Castilla](https://discuss.elastic.co/u/Justin_Castilla)\
**Post date:** [August 28, 2024, 5:18pm UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/8 "2024-08-28T17:18:40Z")

</div>

Hello! This might work, as it doesn't rely on the query\_text field in the query:

```auto
resp = client.search(
    index="<YOUR_INDEX>",
    query={
        "script_score": {
            "query": {
                "match_all": {}
            },
            "script": {
                "source": "cosineSimilarity(params.queryVector, '<DENSE_VECTOR_FIELD>') + 1.0",
                "params": {
                    "queryVector": <YOUR_QUERY_VECTOR>
                }
            }
        }
    },
)
print(resp)

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [September 25, 2024, 5:19pm UTC](https://discuss.elastic.co/t/exact-knn-with-python-api/365542/9 "2024-09-25T17:19:26Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
