ElasticSearch and NEST - How do I construct a simple OR query? -
i'm developing building repository query.
here query trying write.
(exact match on
zipcode
) , ((case-insensitive exact match onaddress1
) or (case-insensitive exact match onsitename
))
in repository, have document looks following:
address1
: 4 myrtle street
sitename
: myrtle street
zipcode
: 90210
and keep getting matches on:
address1
: 45 myrtle street
sitename
: myrtle
zipcode
: 90210
here attempts have not worked:
{ "query": { "bool": { "must": [ { "bool": { "should": [ { "term": { "address1": { "value": "45 myrtle street" } } }, { "term": { "sitename": { "value": "myrtle" } } } ] } }, { "term": { "zipcode": { "value": "90210" } } } ] } } } { "query": { "filtered": { "query": { "term": { "zipcode": { "value": "90210" } } }, "filter": { "or": { "filters": [ { "term": { "address1": "45 myrtle street" } }, { "term": { "sitename": "myrtle" } } ] } } } } } { "filter": { "bool": { "must": [ { "or": { "filters": [ { "term": { "address1": "45 myrtle street" } }, { "term": { "sitename": "myrtle" } } ] } }, { "term": { "zipcode": "90210" } } ] } } } { "query": { "bool": { "must": [ { "span_or": { "clauses": [ { "span_term": { "sitename": { "value": "myrtle" } } } ] } }, { "term": { "zipcode": { "value": "90210" } } } ] } } } { "query": { "filtered": { "query": { "term": { "zipcode": { "value": "90210" } } }, "filter": { "or": { "filters": [ { "term": { "address1": "45 myrtle street" } }, { "term": { "sitename": "myrtle" } } ] } } } } }
does know doing wrong?
i'm writing nest, prefer nest syntax, elasticsearch syntax suffice well.
edit: per @greg marzouka's comment, here mappings:
{ [indexname]: { "mappings": { "[indexname]elasticsearchresponse": { "properties": { "address": { "type": "string" }, "address1": { "type": "string" }, "address2": { "type": "string" }, "address3": { "type": "string" }, "city": { "type": "string" }, "country": { "type": "string" }, "id": { "type": "string" }, "originalsourceid": { "type": "string" }, "placeid": { "type": "string" }, "sitename": { "type": "string" }, "sitetype": { "type": "string" }, "state": { "type": "string" }, "systemid": { "type": "long" }, "zipcode": { "type": "string" } } } } } }
based on mapping, won't able search exact matches on sitename
because it's being analyzed standard analyzer, more tuned full text search. default analyzer applied elasticsearch when 1 isn't explicitly defined on field.
the standard analyzer breaking value of sitename
multiple tokens. example, myrtle street
tokenized , stored 2 separate terms in index, myrtle
, street
, why query matching document. case-insensitive exact match, instead want myrtle street
stored single, lower-cased token in index: myrtle street
.
you set sitename
not_analyzed
, won't subject field analysis chain @ all- meaning values not modified. however, produce single myrtle street
token, work exact matches, case-sensitive.
what need create custom analyzer using keyword tokenizer , lowercase token filter, apply field.
here's how can accomplish nest's fluent api:
// create custom analyzer using keyword tokenizer , lowercase token filter var myanalyzer = new customanalyzer { tokenizer = "keyword", filter = new [] { "lowercase" } }; var response = this.client.createindex("your-index-name", c => c // add customer analyzer index settings .analysis(an => .analyzers(az => az .add("my_analyzer", myanalyzer) ) ) // create mapping type , apply "my_analyzer" sitename field .addmapping<yourtype>(m => m .mapfromattributes() .properties(ps => ps .string(s => s.name(t => t.sitename).analyzer("my_analyzer")) ) ) );
Comments
Post a Comment