rubyprince
rubyprince

Reputation: 17793

Search by size of object type field elastic search

I have a mapping like this:

{
  "post": {
    "properties": {
      "author_gender": {
        "type": "string",
        "index": "not_analyzed",
        "omit_norms": true,
        "index_options": "docs"
      },
      "author_link": {
        "type": "string",
        "index": "no"
      },
      "content": {
        "type": "string"
      },
      "mentions": {
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "profile_image_url": {
            "type": "string"
          },
          "screen_name": {
            "type": "string"
          }
        }
      }
   }
}

I need to search by the size of the mentions object. I have tried this:

{
  "filter": {
    "script": {
      "script": "doc['mentions'].values.length == 2"
    }
  }
}

This is not working. Gives an error

nested: ElasticSearchIllegalArgumentException[No field found for [mentions] in mapping with types [post]];

I have also tried replacing the script part with doc['mentions.id'].value.length == 2. It is also erroring

nested: ArrayIndexOutOfBoundsException[10];

How to query records with mentions object size 2 ?

Upvotes: 13

Views: 8511

Answers (4)

Antony-K
Antony-K

Reputation: 11

I don't know why but it seems to me that Elasticsearch stores array not as array of particular objects. Such pattern worked for me: I used instead

"script": "doc['some_array'].values.size()"

this

"script": "doc['some_array.any_field'].size()"

Should work:

"script": "doc['mentions.id'].size() == 2"

or

"script": "doc['mentions.id'].length == 2"

Upvotes: 0

Its_aggarwal
Its_aggarwal

Reputation: 801

For me, it works like this:

ES version - 7.11.1

I have mapping like this:

{
  "items": {
    "properties": {
      "description": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "quantity": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "value": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

My Query is like this:

{
  "filter": {
    "script": {
      "script": "doc['items.description.keyword'].size() == 2"
    }
  }
}

Upvotes: 0

Sai
Sai

Reputation: 461

The elasticsearch guide recommends using size() instead of length for objects. So try this:

{
 "filter": {
   "script": {
     "script": "doc['mentions.id'].values.size() == 2"
    }
  }
}

All the best.

Upvotes: 14

Thomas Decaux
Thomas Decaux

Reputation: 22661

ElasticSearch will not store array of objects like you think. Instead, multiple arrays are stored for each object properties.

So that's why you must use "sub array" instead.

Upvotes: 3

Related Questions