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.