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