将稀疏向量添加为Elasticsearch中的字段

时间:2019-08-22 14:28:11

标签: python json elasticsearch

最近,Elasticsearch允许在查询中使用向量和稀疏向量。在their documentation之后,我遇到了一个错误(请参阅full details on this question),基本上是:

"type" : "illegal_argument_exception",
"reason" : "Variable [embedding] is not defined."

似乎“嵌入”不是一个成功的领域。

我将文档上传到Elasticsearch如下:

  1. 我为每个文档创建一个json文件
  2. 我在Python db_object = json.load(fp)中加载json文件
  3. 我将这些对象传递给Elasticsearch:es.index(index=my_index, doc_type='sentence', id=db_object['name'], body=db_object)

这是我的json文件的结构(请注意,嵌入是字典,因为它是稀疏向量)。

{"name": "doc_name", "field_1": "doc_id", "field_2": "a_keyword", "text": "a rather long text", "embedding": {"4655": 0.040158602078116556, "4640": 0.040158602078116556}}

但是,如果我进行简单的测试查询,似乎无法进行嵌入。采用以下查询结构:

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "query_string" : {
      "query" : "0.040158602078116556",
      "default_field" : "embedding"
    }
  }
}'

如果我将embedding留在“ default_field”中,则找不到文档。

如果我尝试将4655作为字段(请注意,这是嵌入字典中的键,与我在查询中粘贴的数字相对应),则也不会发生任何事情。

但是,如果字段为embedding.4655,则查询有效。在我看来,这似乎是一个明确的信号,“嵌入”不被理解为稀疏向量的单个字段,而是字典键与“嵌入”结合形成具有数值的独立字段的集合。

另一个暗示可能不正确的提示是,加载这样的文档使Elasticsearch抗议字段太多,而我原以为“嵌入”是一个字段,并且只有一个字段。

我正确吗?我上载有关此特殊字段的文档的方式是否存在缺陷?

1 个答案:

答案 0 :(得分:1)

问题在于,Elasticsearch在推断正确的类型时遇到麻烦。它认为字典中的每个键都是一个新字段(embedding.key)。因此,我们需要提供一个指定类型的映射。以我为例,在创建索引后使用Python中的elasticsearch库:

import requests

uri='http://localhost:9200/my_index/_mapping'

json_body="""{                    
    "properties": {
        "name": {
            "type": "keyword"
        },
        "reference": {
            "type": "keyword"
        },
        "jurisdiction": {
            "type": "keyword"
        },
        "text": {
            "type": "text"
        },
        "embedding": {
            "type": "sparse_vector"
        }
    }
}""")  

headers = {
    'Content-Type': 'application/json',
}

requests.put(uri, headers=headers, data=json_body)