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.
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"
}
}
}
}
}
}
}