Search string in different ways

Vote:
 

Hi,

I need to search a string which contains user details e.g. "firstname surname (reference)" and I need it to search the string against each element but also against a combination e.g. firstname and surname.

I have the code:

var textFilter = searchClient.BuildFilter();
textFilter = textFilter.Or(x => x.SearchTitle.Fuzzy(searchTerm))
.Or(x => x.SearchTitle.AnyWordBeginsWith(searchTerm))
.Or(x => x.SearchTitle.PrefixCaseInsensitive(searchTerm)); ;

search = search.Filter(textFilter);

and this works with searching against each element in the string and returns matches for each element, but for example will not match "Mark A".

For the combination of elements I need to do a contains so that "Mark A" would return a result. I've tried the approach suggested by Joel Abrahamsson at http://joelabrahamsson.com/wildcard-queries-with-episerver-find/

and have added

search = search.WildCardQuery(String.Format("*{0}*", searchTerm), x => x.SearchTitle);

But this does still not match for "Mark A" and behaves the same as not adding the wildcard query.

So I removed the wildcard query and added:

search.For(searchTerm, q =>
{
      q.Query = String.Format("*{0}*", searchTerm);
})
.InField(x => x.SearchTitle)
.GetResult();

And this partially works as follows:

  • Finds "Mark A"
  • Never finds reference (does find reference originally)
  • Intermittently won't find users with firstname only (original version does)

Any suggestions?

Thanks,

Mark

#142692
Dec 18, 2015 13:09
Vote:
 

Have you tried adding some supporting new properties with the most likely variations to the objects you index?

In my experience this is usually easier to do and to follow than bending the query to support every case.

#142709
Dec 18, 2015 22:35
Vote:
 

Hi Johan,

Ok I've updated my filter for the original query to inlcude

.Or(x => x.SearchAuthors.ElementAt(4).Fuzzy(searchTerm))
.Or(x => x.SearchAuthors.ElementAt(4).AnyWordBeginsWith(searchTerm))
.Or(x => x.SearchAuthors.ElementAt(4).PrefixCaseInsensitive(searchTerm));

And it's not finding the reference which is stored at element 4, this is when using:

search.For(searchTerm, q =>
{
      q.Query = String.Format("*{0}*", searchTerm);
})
.InField(x => x.SearchTitle)
.GetResult();

as well

Any thoughts?

#142752
Dec 21, 2015 16:51
Vote:
 

Think of Find as a thing you throw queries at and gets a result back. At query time you don't have access to the in-memory objects, so ElementAt[] won't work.

What I meant by "some supporting new properties" is that I would add the different variations as their own property to have more control over things like boosting, which filtermethod on certain properties etc. For example a property named "string AuthorWithReference { get { $"{firstname} {lastname} {reference}" }}".

You might also try something like:

class SomeContentWithAuthor
{
	SomeContentWithAuthor()
	{
		this.SearchAuthors = { "Johan K", "J Kronberg", "Kronberg Johan", "Johan Kronberg", "Johan" };
	}

	string[] SearchAuthors { get; set; }
}

Then you would do MatchContained on it as exampified here:
http://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-Find/11/DotNET-Client-API/Searching/Filtering/Complex-objects/

#142800
Dec 28, 2015 11:17
* 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.