ruby-on-railsrubyelasticsearchjbuilder

elastic - QueryingParsingException - query does not support - when searching by association field using a filter


I have a model person that has many addresses (association/table name person_addresses) I am trying to give the user the ability to find a person by its address.

When I try to search by address, I get: QueryingParsingException - query does not support [addresses.address]

e.g: /api/v1/search/people?q=aaron&address=scarborough

query:

[ 
   { 
      "query":{ 
         "match":{ 
            "name":"aaron"
         }
      },
      "sort":[ 
         { 
            "id":{ 
               "order":"desc"
            }
         }
      ],
      "filter":{ 
         "bool":{ 
            "must":{ 
               "nested":{ 
                  "path":"addresses",
                  "query":{ 
                     "terms":{ 
                        "addresses.address":"scarborough"
                     }
                  }
               }
            }
         }
      },
      "aggregations":{ 
         "addresses":{ 
            "nested":{ 
               "path":"addresses"
            },
            "aggregations":{ 
               "nested_items":{ 
                  "terms":{ 
                     "field":"addresses.address",
                     "order":{ 
                        "_count":"desc"
                     }
                  }
               }
            }
         }
      }
   }
]

mapping:

  mapping do
    indexes :first_name, type: 'multi_field', fields: {
      first_name: { type: 'string', index: 'analyzed' },
      na_first_name: { type: 'string', index: 'not_analyzed' }
    }
    indexes :middle_name, type: 'multi_field', fields: {
      middle_name: { type: 'string', index: 'analyzed' },
      na_middle_name: { type: 'string', index: 'not_analyzed' }
    }
    indexes :last_name, type: 'multi_field', fields: {
      last_name: { type: 'string', index: 'analyzed' },
      na_last_name: { type: 'string', index: 'not_analyzed' }
    }
    indexes :addresses, type: :nested do
      indexes :location, type: :geo_point, index: :not_analyzed
      indexes :country, type: :string, index: :not_analyzed
      indexes :state, type: :string, index: :not_analyzed
      indexes :address, type: :string
      indexes :county, type: :string, index: :not_analyzed
      indexes :city, type: :string, index: :not_analyzed
      indexes :zip, type: :string, index: :not_analyzed
      indexes :state_id, type: :long
      indexes :county_id, type: :long
      indexes :city_id, type: :long
    end
  end

I have this record indexed:

 {
        "_index": "pl_people",
        "_type": "person",
        "_id": "813106",
        "_score": null,
        "sort": [
            -9223372036854775808
        ],
        "resource": "Person",
        "parameterized": "813106-aaron-mcguire",
        "name": "Aaron McGuire",
        "phone": "813-689-6889",
        "date_of_birth": "1991-03-01",
        "first_name": "Aaron",
        "last_name": "McGuire",
        "addresses": [
            {
                "id": 1,
                "parameterized": "1",
                "address": "123 Scarborough road",
                "zip": "L5A2A9",
                "city": "Ontario",
                "country": "USA",
                "state": "California",
                "location": null,
                "state_id": null,
                "county_id": null,
                "city_id": null
            }
        ],
        "projects": [],
    }

index.json.jbuilder:

# frozen_string_literal: true

json.query do
  if @term.present?
    json.set!(:match, @field => @term)
  else
    json.set!(:match_all, {})
  end
end

json.sort do
  json.child! do
    json.set!(:id, order: 'desc')
  end
end

if [@address].any?(&:present?)
  json.filter do
    json.partial!('people/index/filters')
  end
end

json.aggregations do
  json.addresses do
    json.nested do
      json.set!(:path, 'addresses')
    end
    json.aggregations do
      json.nested_items do
        json.terms do
          json.set!(:field, 'addresses.address')
          json.set!(:order, _count: 'desc')
        end
      end
    end
  end
end

_filters.json.jbuilder:

# frozen_string_literal: true

json.bool do
  json.must do
    if (value = @address).present?
      json.nested do
        json.path('addresses')
        json.query do
          json.set!(:terms, 'addresses.address' => value)
        end
      end
    end
  end
end

index.rb (person search)

# frozen_string_literal: true

module Searching
  module People
    class Index < ::Searching::ApplicationSearching
      self.valid_params = {
        q: { type: :string, on_blank: :remove },
      }

      delegate :aggregations, to: :results

      def initialize(params = {})
        super(params)
      end

      protected

      def klass
        Person
      end

      def search
        @search ||= ClientSearch.new(
          index: [klass].map(&:index_name).join(','),
          body: body,
          size: limit,
          from: offset,
        )
      end

      def body
        query_field = params[:field].present? ? params[:field] : :name
        Searching::TemplateHandler.(
          'people/index',
          term: Searching::Util.sanitize_string(params[:q]),
          field: query_field,
          address: params[:address],
        )
      end

    end
  end
end

GET /pl_people

{ 
   "pl_people":{ 
      "aliases":{ 

      },
      "mappings":{ 
         "person":{ 
            "properties":{ 
               "ac_name":{ 
                  "type":"string",
                  "analyzer":"autocomplete"
               },
               "addresses":{ 
                  "type":"nested",
                  "properties":{ 
                     "address":{ 
                        "type":"string"
                     },
                     "city":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "city_id":{ 
                        "type":"long"
                     },
                     "country":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "county":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "county_id":{ 
                        "type":"long"
                     },
                     "id":{ 
                        "type":"long"
                     },
                     "location":{ 
                        "type":"geo_point"
                     },
                     "parameterized":{ 
                        "type":"string"
                     },
                     "state":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "state_id":{ 
                        "type":"long"
                     },
                     "zip":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "author":{ 
                  "type":"string",
                  "index":"not_analyzed"
               },
               "body":{ 
                  "type":"string",
                  "analyzer":"remove_html",
                  "fields":{ 
                     "ns_body":{ 
                        "type":"string",
                        "analyzer":"remove_html_stopwords"
                     }
                  }
               },
               "charities":{ 
                  "type":"nested",
                  "properties":{ 
                     "email":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "id":{ 
                        "type":"long"
                     }
                  }
               },
               "community":{ 
                  "properties":{ 
                     "name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "parameterized":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "slug":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "created_at":{ 
                  "type":"date",
                  "format":"dateOptionalTime"
               },
               "date_of_birth":{ 
                  "type":"date",
                  "format":"dateOptionalTime"
               },
               "description":{ 
                  "type":"string"
               },
               "employments":{ 
                  "type":"nested",
                  "properties":{ 
                     "email":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "employment_status":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "foia_contact":{ 
                        "type":"boolean"
                     },
                     "id":{ 
                        "type":"long"
                     },
                     "phone":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "phone_extension":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "first_name":{ 
                  "type":"string",
                  "fields":{ 
                     "na_first_name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "last_name":{ 
                  "type":"string",
                  "fields":{ 
                     "na_last_name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "market":{ 
                  "properties":{ 
                     "name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "parameterized":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "slug":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "middle_name":{ 
                  "type":"string",
                  "fields":{ 
                     "na_middle_name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "most_recent_organization":{ 
                  "properties":{ 
                     "description":{ 
                        "type":"string"
                     },
                     "id":{ 
                        "type":"long"
                     },
                     "name":{ 
                        "type":"string"
                     },
                     "parameterized":{ 
                        "type":"string"
                     },
                     "phone":{ 
                        "type":"string"
                     }
                  }
               },
               "name":{ 
                  "type":"string",
                  "fields":{ 
                     "na_name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "ngram_name":{ 
                        "type":"string",
                        "analyzer":"my_start"
                     },
                     "ns_name":{ 
                        "type":"string",
                        "analyzer":"no_stopwords"
                     }
                  }
               },
               "organizations":{ 
                  "properties":{ 
                     "name":{ 
                        "type":"string"
                     },
                     "parameterized":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "package":{ 
                  "properties":{ 
                     "name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "parameterized":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "slug":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "parameterized":{ 
                  "type":"string",
                  "index":"not_analyzed"
               },
               "phone":{ 
                  "type":"string"
               },
               "photo":{ 
                  "properties":{ 
                     "large":{ 
                        "type":"string"
                     },
                     "medium":{ 
                        "type":"string"
                     },
                     "teaser":{ 
                        "type":"string"
                     },
                     "thumb":{ 
                        "type":"string"
                     },
                     "url":{ 
                        "type":"string"
                     }
                  }
               },
               "projects":{ 
                  "properties":{ 
                     "id":{ 
                        "type":"long"
                     },
                     "name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "parameterized":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "slug":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "public_offices":{ 
                  "type":"nested",
                  "properties":{ 
                     "email":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "employment_status":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "id":{ 
                        "type":"long"
                     }
                  }
               },
               "published":{ 
                  "type":"string",
                  "index":"not_analyzed"
               },
               "region":{ 
                  "properties":{ 
                     "name":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "parameterized":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     },
                     "slug":{ 
                        "type":"string",
                        "index":"not_analyzed"
                     }
                  }
               },
               "resource":{ 
                  "type":"string"
               },
               "short_description":{ 
                  "type":"string"
               },
               "show_path":{ 
                  "type":"string"
               },
               "time":{ 
                  "type":"date",
                  "format":"dateOptionalTime"
               },
               "updated_at":{ 
                  "type":"date",
                  "format":"dateOptionalTime"
               }
            }
         }
      },
      "settings":{ 
         "index":{ 
            "creation_date":"1581684793139",
            "analysis":{ 
               "filter":{ 
                  "english_stop":{ 
                     "type":"stop",
                     "stopwords":[ 
                        "a",
                        "an",
                        "and",
                        "are",
                        "as",
                        "at",
                        "be",
                        "but",
                        "by",
                        "for",
                        "if",
                        "in",
                        "into",
                        "is",
                        "it",
                        "no",
                        "not",
                        "of",
                        "on",
                        "or",
                        "such",
                        "that",
                        "the",
                        "their",
                        "then",
                        "there",
                        "these",
                        "they",
                        "this",
                        "to",
                        "was",
                        "with"
                     ]
                  },
                  "my_edge":{ 
                     "min_gram":"2",
                     "side":"front",
                     "type":"edgeNGram",
                     "max_gram":"18"
                  }
               },
               "analyzer":{ 
                  "no_stopwords":{ 
                     "type":"stop",
                     "stopwords":"_english_"
                  },
                  "comma":{ 
                     "pattern":",",
                     "type":"pattern"
                  },
                  "default":{ 
                     "filter":[ 
                        "standard",
                        "lowercase",
                        "english_stop",
                        "word_delimiter"
                     ],
                     "tokenizer":"standard"
                  },
                  "remove_html_stopwords":{ 
                     "filter":"stop",
                     "char_filter":"html_strip",
                     "type":"custom",
                     "stopwords":"_english_",
                     "tokenizer":"lowercase"
                  },
                  "autocomplete":{ 
                     "filter":[ 
                        "lowercase",
                        "apostrophe"
                     ],
                     "tokenizer":"keyword"
                  },
                  "my_start":{ 
                     "filter":[ 
                        "asciifolding",
                        "lowercase",
                        "my_edge"
                     ],
                     "tokenizer":"whitespace"
                  },
                  "remove_html":{ 
                     "filter":"lowercase",
                     "char_filter":"html_strip",
                     "type":"custom",
                     "tokenizer":"standard"
                  }
               }
            },
            "number_of_shards":"5",
            "number_of_replicas":"1",
            "version":{ 
               "created":"1070699"
            },
            "uuid":"LZrnPjxiTwyNf-Ggo3bXtw"
         }
      },
      "warmers":{ 

      }
   }
}

Any naming conventions I am not following? I tried changing person_address for address on filters.json and index.json, but still didnt have any success.


Solution

  • So i reinstall es 1.7 and made some try, simplified your data.

    the error was in the "terms" in the filter, you have to use a term / match instead. If you want to add multiple condition it seems you need to build boolean query with a term on each.

    Moreover i cant understand why you use a post_filter here (filter at top level = post_filter in es > 2.X), can you explain it?

    This is what i done using HEAD if you want reproduce (i simplify the mappings, keeping only relevant fields).

    hope it s help.

    http://localhost:9200/pl_people/ (POST)

    { 
          "mappings":{ 
             "person":{ 
                "properties":{ 
                   "ac_name":{ 
                      "type":"string"
                   },
                   "addresses":{ 
                      "type":"nested",
                      "properties":{ 
                         "address":{ 
                            "type":"string"
                         },
                         "city":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         },
                         "city_id":{ 
                            "type":"long"
                         },
                         "country":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         },
                         "county":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         },
                         "county_id":{ 
                            "type":"long"
                         },
                         "id":{ 
                            "type":"long"
                         },
                         "location":{ 
                            "type":"geo_point"
                         },
                         "parameterized":{ 
                            "type":"string"
                         },
                         "state":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         },
                         "state_id":{ 
                            "type":"long"
                         },
                         "zip":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         }
                      }
                   },
                   "date_of_birth":{ 
                      "type":"date",
                      "format":"dateOptionalTime"
                   },
                   "first_name":{ 
                      "type":"string",
                      "fields":{ 
                         "na_first_name":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         }
                      }
                   },
                   "last_name":{ 
                      "type":"string",
                      "fields":{ 
                         "na_last_name":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         }
                      }
                   },
                   "name":{ 
                      "type":"string",
                      "fields":{ 
                         "na_name":{ 
                            "type":"string",
                            "index":"not_analyzed"
                         },
                         "ngram_name":{ 
                            "type":"string"
                         },
                         "ns_name":{ 
                            "type":"string"
                         }
                      }
                   },
                   "parameterized":{ 
                      "type":"string",
                      "index":"not_analyzed"
                   },
                   "phone":{ 
                      "type":"string"
                   },
                   "resource":{ 
                      "type":"string"
                   }
                }
             }
          }
    }
    

    http://localhost:9200/pl_people/person/813106 (POST)

    {
            "ac_name": "Aaron McGuire",
            "resource": "Person",
            "parameterized": "813106-aaron-mcguire",
            "name": "Aaron McGuire",
            "phone": "813-689-6889",
            "date_of_birth": "1991-03-01",
            "first_name": "Aaron",
            "last_name": "McGuire",
            "addresses": [
                {
                    "id": 1,
                    "parameterized": "1",
                    "address": "123 Scarborough road",
                    "zip": "L5A2A9",
                    "city": "Ontario",
                    "country": "USA",
                    "state": "California"
                }
            ]
        }
    

    http://localhost:9200/pl_people/person/_search/ (post)

    {
      "query": {
        "match": {
          "name": "aaron"
        }
      },
      "sort": [
        {
          "id": {
            "order": "desc"
          }
        }
      ],
      "filter": {
        "bool": {
          "must": {
            "nested": {
              "path": "addresses",
              "query": {
                "term": {
                  "addresses.address": "scarborough"
                }
              }
            }
          }
        }
      },
      "aggregations": {
        "addresses": {
          "nested": {
            "path": "addresses"
          },
          "aggregations": {
            "nested_items": {
              "terms": {
                "field": "addresses.address",
                "order": {
                  "_count": "desc"
                }
              }
            }
          }
        }
      }
    }