London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Search for text containing "Foo"

Vote:
 

Is it possible to search for a part of a word? Ie if the query is "Foo" I can't figure out how to get a match on "BarFooBar" or "BarFoo". Something similar to .AnyWordBeginsWith("Foo") would be nice.

#61223
Sep 12, 2012 8:18
Vote:
 

Looking at the documentation I would say that the FuzzyQuery would be able to find that for you. Did you try that one? 

#61241
Sep 12, 2012 15:14
Vote:
 

If I'm not misunderstanding thats the built in full text search in EPiServer Framework, not the product EPiServer Find.

#61242
Sep 12, 2012 15:24
Vote:
 

Right you are! (guess I should read the question more carefully) ;)

 

How about the morelike then? http://find.episerver.com/Documentation/dotnet-api-more-like-related-documents

#61243
Sep 12, 2012 15:29
Vote:
 

At the moment there's no "fluent API method" for wildcard queries in the Find .NET API. Below is an extension method that adds such functionality. It requires a query (string) and a field to apply the query to (an expression). By default it doesn't add any wildcard characters but the query type will parse "*" (any number of characters) and "?" (a single character). The reason it requires a field is that a wildcard query can be slow and therefor it's good to conciously make a decision about what field, or fields, to apply it to.

I'll see if I can create a more polished method later which I'll probably blog about if so.

public static class SearchExtensions
{
    public static ITypeSearch<T> AddWildCardQuery<T>(
        this ITypeSearch<T> search, 
        string query, 
        Expression<Func<T, string>> fieldSelector)
    {
        var fieldName = search.Client.Conventions.FieldNameConvention
            .GetFieldNameForAnalyzed(fieldSelector);
        var wildcardQuery = new WildcardQuery(fieldName, query.ToLowerInvariant());
        return new Search<T, WildcardQuery>(search, context =>
        {
            if (context.RequestBody.Query != null)
            {
                var boolQuery = new BoolQuery();
                boolQuery.Should.Add(context.RequestBody.Query);
                boolQuery.Should.Add(wildcardQuery);
                boolQuery.MinimumNumberShouldMatch = 1;
                context.RequestBody.Query = boolQuery;
            }
            else
            {
                context.RequestBody.Query = wildcardQuery;
            }
        });
    }
}

Basic usage:

var query = "Foo";

//Make it match any word containing foo
query = "*" + query + "*";

//Make it match any word ending with foo
//query = query + "*";

var result = client.Search<Recipe>()
    .AddWildCardQuery(query, x => x.Name)
    .GetResult();    

Use the method after having called the For or MoreLike methods but before any calls to Filter. Example:

var result = client.Search<Recipe>(Language.Swedish)
    .For("Foo")
    .InField(x => x.Name)
    .InField(x => x.Instructions)
    .AddWildCardQuery("*Foo*", x => x.Name)
    .Filter(x => !x.ID.Match(42))
    .GetResult();

Again, keep in mind that wildcard queries, especially those starting with * or ? can be slow so use them only when it's really needed, preferably on a limited number of fields.   

#61291
Edited, Sep 14, 2012 10:30
Vote:
 

Awesome Joel!

#61292
Sep 14, 2012 10:39
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.