pangpang
pangpang

Reputation: 8821

Elasticsearch how to match a two-dimensional array?

I have a special data structure. For example:

{
 "name": "test",
 "age": 20,
 "gender": "M",
 "custom": [
     ["tel", "1234567"], ["weibo", "abcde"], ["weixin", "abcdefg"]......
 ]
}

{
 "name": "test1",
 "age": 30,
 "gender": "F",
 "custom": [
     ["电话", "1234567"], ["微博", "abcde"], ["微信", "abcdefg"]......
 ]
}

The custom filed is a two-dimensional array, I want to search ["tel", "1234567"]. How to make it possible by ES?

Upvotes: 0

Views: 2494

Answers (1)

Val
Val

Reputation: 217474

You need to change the way you index your custom array. The problem is that ES will flatten it out during analysis, so that custom will contain the tokens tel, 1234567, weibo, abcde, etc, i.e. the 2D structure is lost.

If you want to be able to query tel and 1234566, you need to define your custom field as a nested datatype, similar to this.

PUT index
{
  "mappings": {
    "type": {
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        },
        "gender": {
          "type": "string"
        },
        "custom": {
          "type": "nested",
          "properties": {
            "key": {
              "type": "string"
            },
            "value": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}

Then you can index your documents like this:

PUT index/type/1
{
 "name": "test",
 "age": 20,
 "gender": "M",
 "custom": [
     {"key": "tel", "value": "1234567"}, 
     {"key": "weibo", "value": "abcde"},
     {"key": "weixin", "value": "abcdefg"}
 ]
}

Finally, you can query "tel 1234567" and get the documents you expect with the following query:

POST index/type/_search
{
  "query": {
    "nested": {
      "path": "custom",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "custom.key": "tel"
              }
            },
            {
              "term": {
                "custom.value": "1234567"
              }
            }
          ]
        }
      }
    }
  }
}

Upvotes: 3

Related Questions