Reputation: 409
I am attempting to perform a query with filters. I can get it to filter on some properties but not the one I need. Here is my model:
public class IndexItem
{
public DateTime CreatedDate { get; set; }
[ElasticProperty(Index = FieldIndexOption.Analyzed)]
public String Name { get; set; }
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
public String Role { get; set; }
public bool ExcludeFromSearch { get; set; }
}
The query I start off with is:
var esQuery = Query<IndexItem>.QueryString(x => x.OnFields(f => f.Name).Query(String.Format("{0}*", query)).Boost(1.2));
If I filter on CreatedDate or ExcludeFromSearch it works like I would think, But I cannot get it to work for Role.
filter.Add(Filter<IndexItem>.Term(x => x.CreatedDate, searchDate)); // Works
filter.Add(Filter<IndexItem>.Term(x => x.Role, role)); // Never Returns a result
var searchResults = client.Search<IndexItem>(s => s
.Types(typeof(IndexItem))
.From(start)
.Size(count)
.Query(esQuery)
.Filter(x => x.And(filter.ToArray()))
); // Returns empty if I filter by Role, but works if i filter by CreatedDate
The only difference I can see is that Role has the annotation [ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]. Does this make it not allowed to be filtered by?
Here is an example output for a query I put in the browser:
{"took":47,"timed_out":false,"_shards":{"total":10,"successful":10,"failed":0},"hits":{"total":1,"max_score":5.9272537,"hits":[{"_index":"default-index","_type":"indexitem","_id":"3639","_score":5.9272537,"_source":{
"properties": {
"MainBody": "Test Role Search"
},
"id": "3639",
"createdDate": "2015-05-08T14:34:33",
"name": "Role Test",
"url": "/my-role-test/",
"role": "Admin",
"excludeFromSearch": false
}}]}}
Upvotes: 0
Views: 362
Reputation: 738
The [ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
attribute on the Role field defines a mapping property and means that the contents of this field will not pass through the analysis process before being indexed. See here for the official documentation on mappings and here for the documentation on the analysis proces. On the contrary the contents of the Name field will pass from the analysis process before being indexed.
The term filter that you are using, filters documents that have fields that contain this term as provided, without passing the term from the analysis process (see here).
Example: If you are using the standard analyzer and you want to index an IndexItem with Name="Data", then the analyzer would transform the "Data" to "data" and would insert this term in the inverted index. Using the same analyzer and wanting to index an IndexItem with Role="Data" then the "Data" term would be saved in the inverted index since the contents of the Role field are excluded from the analysis procedure.
Thus, if you want to make a term filter to match the previous documents on the Role field, then the value to filter by is "Data" (exactly the same as the one in the indexed document). If you want to make a term filter to match the previous documents on the Name field, then the value to filter by is "data". Keep in mind that it's a good practice to use the same analyzer when indexing and querying your data.
Upvotes: 1