nskalis
nskalis

Reputation: 2382

elastic: HOW-TO search a nested field ? [not working]

if i have a JSON document indexed into Elasticsearch, like the following:

"_source": {
          "pid_no": 19321,
          "aggregator_id": null,
          "inet_family": "ipv4-unicast",
          "origin_code": "igp",
          "extended_community": null,
          "atomic_aggregate": null,
          "adv_type": "announce",
          "local_preference": 250,
          "med_metric": 0,
          "time_stamp": 1447534931,
          "net_mask": "23",
          "prefix4_": {
            "last": 222,
            "first": 111
          },
          "counter_no": 69668,
          "confederation_path": "",
          "as_set": null,

and i have tried successfully to filter all of the keys of the doc, but, except the nested ones.

the query looks like:

GET /SNIP!/SNIP!/_search?routing=SNIP! 
{
  "query": {
    "bool": {
      "must": {
        "query": {
          "match_all": {}
        }
      },
      "filter": {
        "bool": {
          "filter": [
            {
              "range": {
                "local_preference": {
                  "gt": 150,
                  "lte": 250
                }
              }
            },
>>> if i remove the filter below, matches the document.
>>> when i apply the filter, i get 0 hits
            {
              "and": [
                {
                  "range": {
                    "prefix4_.first": {
                      "lte": 200
                    }
                  }
                },
                {
                  "range": {
                    "prefix4_.last": {
                      "gte": 200
                    }
                  }
                }
              ]
            }
          ]
        }
      }
    }
  }
}

it goes without saying that the mapping is done using integers in the corresponding fields (prefix4_.first,prefix4_.last)

could you please advise on why the filtering does not work ?

EDIT: the mapping looks like this

{
    "mappings": {
        "_default_": {
            "_all": { "enabled": False },
            "dynamic": True,
            "_routing": { "required": True },
            "properties": {
                "pid_no": { "type": "string", "index": "not_analyzed", "store": "no" },
                "counter_no": { "type": "long", "store": "no" },
                "time_stamp": { "type": "date", "format": "epoch_second", "store": "no" },
                "host_name": { "type": "string", "index": "not_analyzed", "store": "no" },
                "local_ip": { "type": "ip", "store": "no" },
                "peer_ip": { "type": "ip", "store": "no" },
                "local_asn": { "type": "string", "index": "not_analyzed", "store": "no" },
                "peer_asn": { "type": "string", "index": "not_analyzed", "store": "no" },

                "inet_family": { "type": "string", "index": "not_analyzed", "store": "no" },
                "next_hop": { "type": "ip", "store": "no" },
                "net_block": { "type": "string", "index": "analyzed", "store": "no" },

                "as_path": { "type": "string", "index": "analyzed", "store": "no" },
                "cluster_list": { "type": "string", "index": "not_analyzed", "store": "no" },
                "confederation_path": { "type": "string", "index": "not_analyzed", "store": "no" },
                "local_preference": { "type": "integer", "store": "no" },
                "originator_ip": { "type": "ip", "store": "no" },
                "origin_code": { "type": "string", "index": "not_analyzed", "store": "no" },
                "community_note": { "type": "string", "index": "analyzed", "store": "no" },
                "med_metric": { "type": "long", "store": "no" },
                "atomic_aggregate": { "type": "boolean", "store": "no" },
                "aggregator_id": { "type": "string", "index": "analyzed", "store": "no" },
                "as_set": { "type": "string", "index": "analyzed", "store": "no" },
                "extended_community": { "type": "string", "index": "not_analyzed", "store": "no" },

                "adv_type": { "type": "string", "index": "not_analyzed", "store": "no" },

                "prefix_": { "type": "string", "index": "not_analyzed", "store": "no" },
                "net_mask": { "type": "integer", "store": "no" },
                "prefix4_": {
                    "type": "nested",
                    "properties": {
                        "first": { "type": "integer", "store": "no" },
                        "last": { "type": "integer", "store": "no" }
                    }
                },
                "prefix6_": {
                    "type": "nested",
                    "properties": {
                        "lofirst": { "type": "long", "store": "no" },
                        "lolast": { "type": "long", "store": "no" },
                        "hifirst": { "type": "long", "store": "no" },
                        "hilast": { "type": "long", "store": "no" }
                    }
                }

            }
        }
    },
    "settings" : {
        "number_of_shards": 1,
        "number_of_replicas": 0,
        "index": {
            "store.throttle.type": "none",
            "memory.index_buffer_size": "20%",
            "refresh_interval": "1m",
            "merge.async": True,
            "merge.scheduler.type": "concurrent",
            "merge.policy.type": "log_byte_size",
            "merge.policy.merge_factor": 15,
            "cache.query.enable": True,
            "cache.filter.type": "node",
            "fielddata.cache.type": "node",
            "cache.field.type": "soft"
        }
    }
}

Upvotes: 0

Views: 1820

Answers (2)

hudsonb
hudsonb

Reputation: 2294

Elasticsearch provides multiple ways of mapping nested documents. You are using nested which indexes nested documents as separate documents behind the scenes and as such querying them requires the use of a nested query.

The simplest way of indexing nested JSON like you've shown is using the object type mapping. This would allow you to query the field the way you were expecting, however Elasticsearch flattens the hierarchy which may not be acceptable for you.

Upvotes: 1

user3775217
user3775217

Reputation: 4803

use nested filters to filter your documents on nested fields. https://www.elastic.co/guide/en/elasticsearch/reference/1.4/query-dsl-nested-filter.html

{
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "peer_ip": "pqr",
                                "_cache": true
                            }
                        },
                        {
                            "nested": {
                                "filter": {
                                    "bool": {
                                        "must": [
                                            {
                                                "terms": {
                                                    "first": [
                                                        "xyz"
                                                    ],
                                                    "_cache": true
                                                }
                                            }
                                        ]
                                    }
                                },
                                "path": "prefix4_",
                                "inner_hits": {}
                            }
                        },
                        {
                            "terms": {
                                "pid_no": [
                                    "yyu"
                                ],
                                "_cache": true
                            }
                        }
                    ]
                }
            }
        }
    }
}

Upvotes: 0

Related Questions