Vycka / ElasticSearch.Client

User-Friendly ElasticSearch c# client for Selecting and Aggregating data queries.
GNU General Public License v2.0
10 stars 1 forks source link

..Wildcard Query? #6

Open skind opened 8 years ago

skind commented 8 years ago

Hey Vycka, the Wildcard search would be a good think - what do you think about? Best regards from a fan of this great lib, skind

Vycka commented 8 years ago

Hello, sorry for the delay.

Currently wildcards are only available through lucene filters. Eg: new LuceneFilter("Search.Field:\"Some*Wildcard\"")

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax

Are you need something more specific? could you specify?

skind commented 8 years ago

Hey Vycka, (Sorry for answering so late - I was on vacation) I try to specify: I have some 'fields' in my Elastic-DB I want to query with some simple String Operations like 'StartsWith' (e,g. '12345*') or 'EndsWith' or in the best case with Regex. Thankx in advance you for your effort, skind

Vycka commented 8 years ago

well, currently you can do it with same mentioned LuceneFilter

new LuceneFilter("Search.Field:\"StartsWith*\"");

new LuceneFilter("Search.Field:\"*EndsWith\""); // Performance-wise not recommended.

new LuceneFilter("Search.Field:/YourRegExp/")

If that's not enough, could you elaborate?

skind commented 8 years ago

..seems that I can solve my problem with this approach. Will try and give response. Thankx for your effort, skind

skind commented 8 years ago

..I tried the several suggested LuceneFilter(s) - but with no success! --> this.Filtered.Filters.Add(FilterType.Must,( new LuceneFilter( string.Format("{0}:{1}_", Type, TVal)); I'm using Fiddler to see what is requested (here is the Fiddler-JSON with my own simple Notation): --> query.filtered.filter.bool.must.fquery.query.querystring.query=TYPE:"70N100" I read in the elastic doc that there is a Parameter 'analyze_wildcard' : "By default, wildcards terms in a query string are not analyzed. By setting this value to true, a best effort will be made to analyze those as well" But where to set this Parameter? Any ideas, skind

Vycka commented 8 years ago

Well, one thing to consider, when executing wildcard query: A property, on which you execute your search - must be analyzed. (By default ES does just that in dynamically structured documents).

As for the parameter in the query it self. at this moment i have no access to ES database to test things out. However, I can offer some advice in how to implement these by your self if needed. (Also if you need, i can give you my Skype id if you have some questions in the process).

As for the example, I created a custom FilterComponent, which you can paste anywhere in your project and use it as part of the query [ e.g. new MyCustomLuceneFilter("Search.Field:\"StartsWith*\""); ]

http://pastebin.com/H4SffMJ7

On line 38 i added analyze_wildcard = true, which should add your mentioned parameter to the query. You can try to play/customize this sample and see if it does what you need to do.

Vycka commented 8 years ago

Btw, tell me if this helps.

skind commented 8 years ago

Hey Vicky, thanks for your example! But it didn't work with this approach - but I was able to implement a Lucene-Filter: Instead of a "Full Text Query" I used the "Term Level Query" -> "Wildcard Query": My code is now: public ExpandoObject BuildRequestComponent() { object queryObject = new { query = new { wildcard = new { TYPE = _querystring, // only for this field -> should be corrected } }, _chache = Cache, }; ExpandoObject result = new ExpandoObject(); result.Add("fquery", queryObject); } ( Sorry, I am not connected to the Internet for security reasons) This workd with Wildcard for epecially this field - I know this is very unflexible, but maybe with your experience you can give me a hint now to implement this Filter for any field I have in my datasource? Best regards, skind

Vycka commented 8 years ago

Well I'l look into this problem once I have more time (probably next week) and make a solution and add it to nuget package.

as for making this to work with any field, you should do something like that:

Replace this:

object queryObject = new { query = new { wildcard = new { TYPE = _querystring, // only for this field -> should be corrected } }, _chache = Cache, };

with this

ExpandoObject wildcardParams= new ExpandoObject();

wildcardParams.Add("TYPE", _querystring); // Replace "TYPE" with the field, that you want.

object queryObject = new { query = new { wildcard = wildcardParams }, _chache = Cache, };

Not tested, but I hope this compiles and runs :)

Let me know if this works.

skind commented 8 years ago

GREAT! It compiles and runs correctly! This will be a good feature for your lib. Thankx a lot and best regards. By the way, building on your example I implemented now an ExistsTermFilter: "Term Level Queries" -> "Exists Query". This is helpful when a dataset not always has all fields, e.g. depending on criterias, and you want to find all these ones.