从elasticsearch查询中获取指定的no数组元素

时间:2015-08-18 15:12:20

标签: arrays elasticsearch

我的弹性搜索索引在其记录中有一个数组。 假设字段名称为“ samples ”,数组为:

  

[ “ABC”, “XYZ”, “MNP” .....]

所以有任何查询,以便我可以指定要从数组中检索的元素的数量。 假设我想要检索到的记录应该只有样本数组中的前2个元素

1 个答案:

答案 0 :(得分:0)

假设你有一个字符串数组作为文档。我脑子里有几个可能对你有帮助的想法。

PUT /arrayindex/
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "spacelyzer": {
            "tokenizer": "whitespace"
          },
          "commalyzer": {
            "type": "custom",
            "tokenizer": "commatokenizer",
            "char_filter": "square_bracket"
          }
        },
        "tokenizer": {
          "commatokenizer": {
            "type": "pattern",
            "pattern": ","
          }
        },
        "char_filter": {
          "square_bracket": {
            "type": "mapping",
            "mappings": [
              "[=>",
              "]=>"
            ]
          }
        }
      }
    }
  },
  "mappings": {
    "array_set": {
      "properties": {
        "array_space": {
          "analyzer": "spacelyzer",
          "type": "string"
        },
        "array_comma": {
          "analyzer": "commalyzer",
          "type": "string"
        }
      }
    }
  }
}

POST /arrayindex/array_set/1
{
  "array_space": "qwer qweee trrww ooenriwu njj"
}

POST /arrayindex/array_set/2
{
  "array_comma": "[qwer,qweee,trrww,ooenriwu,njj]"
}

上面的DSL接受两种类型的数组,一种是以空格分隔的字符串,其中每个字符串表示一个数组元素,另一种是由您指定的数组类型。这个数组可以在Python和python中使用,如果你索引这样一个文档,它会自动转换为字符串,即["abc","xyz","mnp".....]将被转换为"["abc","xyz","mnp".....]"

spacelyzer根据空格进行标记,commalyzer根据逗号进行标记,并从字符串中删除[ and ]

现在,如果你像这样使用Termvector API:

GET arrayindex/array_set/1/_termvector
{
  "fields" : ["array_space", "array_comma"],
  "term_statistics" : true,
  "field_statistics" : true
}

GET arrayindex/array_set/2/_termvector
{
  "fields" : ["array_space", "array_comma"],
  "term_statistics" : true,
  "field_statistics" : true
}

您可以简单地从他们的回复中获取元素的位置,例如找到"njj"使用

的位置
  • termvector_response["term_vectors"]["array_comma"]["terms"]["njj"]["tokens"][0]["position"]

  • termvector_response["term_vectors"]["array_space"]["terms"]["njj"]["tokens"][0]["position"]

两者都会给你4这是指定数组中的实际索引。我建议您使用whitespace类型设计。

这个的Python代码可以是:

from elasticsearch import Elasticsearch

ES_HOST = {"host" : "localhost", "port" : 9200}
ES_CLIENT = Elasticsearch(hosts = [ES_HOST], timeout = 180)

def getTermVector(doc_id):
    a = ES_CLIENT.termvector\
        (index = "arrayindex",
            doc_type = "array_set",
            id = doc_id,
            field_statistics = True,
            fields = ['array_space', 'array_comma'],
            term_statistics = True)
    return a

def getElements(num, array_no):
    all_terms = getTermVector(array_no)['term_vectors']['array_space']['terms']
    for i in range(num):
        for term in all_terms:
            for jsons in  all_terms[term]['tokens']:
                if jsons['position'] == i:
                    print term, "@ index", i


getElements(3, 1)

# qwer @ index 0
# qweee @ index 1
# trrww @ index 2