Do we have anything like contains in Unified search? - elasticsearch

I have this line of code
query = query.Filter(i =>
(
!i.MatchTypeHierarchy(typeof(InfoPage))
| (((InfoPage)i).SearchSubsection().Exists()
& ((InfoPage)i).GetSearchSubSection().Contains(SOMETHING))
)
); // I want to check if it contains
I want to check if there is anything like a string contains a substring in FIND query. 
Thanks for help in advance. :)

First things first, you are casting to InfoPage which indicates that you shouldn't be using Unified search, instead use the typed search feature.
Second, contains would typically be referred to as wildcard search.
I wrote a typed search wildcard method a while ago, see https://www.herlitz.io/2016/09/19/episerver-find-wildcard-searching/
public static class SearchExtensions
{
public static IQueriedSearch<T> WildCardSearch<T>(this ITypeSearch<T> search, string query)
{
return search.For<T>(query, q => q.Query = string.Concat("*", query, "*"));
}
}
Usage example
var result = SearchClient.Instance.Search<InfoPage>()
.WildCardSearch(query)
.OrderByDescending(x => x.Name)
.FilterForVisitor()
.GetContentResult();

Related

Create a CSV of class members from a list<T>

I have a List of a Simple Struct that contains int's and strings.
Struct:
public struct ErrorType
{
public int RowNumber;
public int ColumnNumber;
public string ErrorMessage;
}
On of My methods return A list of these structs.
I want to convert each member in the list to its string form and separate it by a comma so that List is now an Array of strings. I could write a function to do this manually but I'd perfer to use linq to have a cleaner solution.
Having the array of strings I'll write it to a file using
string path = #"c:\temp\MyTest.txt";
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
List<ErrorType> ErrorTypesList = GetErrors();
//do some work to iterate over the members and do a string.join after
string[] ErrorListArray = ErrorTypesList.foreach( e => { });
File.WriteAllLines(path, createText);
}
does anyone have suggestions on how to fill in the foreach so that it returns each members in its ToString form followed by a comma?
The only way you'd be able to use LINQ for property iteration is if you're using reflection, and you shouldn't do that unless you absolutely have to (which it really doesn't look like you do).
The best you can do, though, still isn't too bad.
var rows = ErrorTypesList
.Select(c => "\"" + string.Join("\",\"", c.RowNumber, c.ColumnNumber, c.ErrorMessage) + "\"");
File.WriteAllLines(path, rows);
I took the liberty of putting fields in quotes as well, you may or may not want that, but it's easy to fix that code to do what you do want. You might also want to add in some escape logic, pending what sorts of contents c.ErrorMessage might have.
You could also use string.Format if you're more comfortable with that, but it doesn't really make a difference here.
var rows = ErrorTypesList
.Select(c => string.Format("\"{0}\", \"{1}\", \"{2}\"", c.RowNumber, c.ColumnNumber, c.ErrorMessage));
It seems you want something like this:
string[] ErrorListArray = ErrorTypesList
.Select(e => string.Join(",", e.RowNumber, e.ColumnNumber, e.ErrorMessage))
.ToArray();

searching by special character on linq

I need a searching process on linq like this. For example, I will make searching on Name column,and user enters "Ca?an" word to textbox. Question mark will e used for sprecial search character for this sitution.
It will search by Name column and, find Canan,Calan,Cazan etc.
I hope I can explain my problem correctly.
Can anyone give me an idea about this linq query. Thank in advance...
You can use this regular expression (if you are using C#) to check for the "Ca?an".
string d = "DDDDDDDDDDCasanDDDDDDDDDD";
Regex r = new Regex(#"Ca([a-zA-Z]{1})an");
string t = r.Match(d).Value;
Output will be:
"Casan"
You have all your colum stored in a database, then do something like:
List<Person> list = new List<Person>(); //Filled
var res = list.Select(x => r.Match(x.Name));
Output will be a IEnumerable with all the "Persons" who contains in the Name "Ca?an", being ? no matter which letter
You need to convert your search-syntax into an existing search-engine - I'd suggest Regex. So the steps will be:
Safely convert the entered search-string into Regex-pattern
Perform the search in Linq on name-property
Solution:
1: Safely convert search string by replacing '?' with Regex-version of wildchar:
var userInput = "Ca?an";
var regexPattern = Regex.Escape(userInput).Replace(#"\?", ".");
2: Perform search in Linq (assuming itemList implements IEnumerable):
var results = itemList.Where(item => Regex.IsMatch(item.Name, regexPattern));
Hope this helps!

How do I check if a Guid value is inside a LIST of Structures?

How do I check if a Guid value is inside a LIST of Structures?
public struct Info
{
public Guid EntityTypeID;
public String Name;
}
List<Info> InfoList = <function which populates the list of Struct>
...
var values = ctx.EntityValues.Where(v => v.EntityID == e.ID
&& InfoList.Contains(v.EntityTypeItemID)).ToList(); <=== problem here!
//or something like: InfoList[i].EntityTypeID.Contains(v.EntityTypeItemID)).ToList();
Thank you
I suspect you're looking for Any:
... InfoList.Any(x => x.EntityTypeID == v.EntityTypeItemID)
You can't use Contains, because you're looking for something which matches part of the item.
(I'd also strongly discourage using public fields and indeed having mutable structures at all, but that's a different matter.)
Another option would be to create a list of the GUIDs you're interested in:
var guids = InfoList.Select(x => x.EntityTypeID).ToList();
Then you can use:
... guids.Contains(v.EntityTypeItemID)
That may work where the previous code didn't, as it moves the extraction of the type ID out of the main query.

How to extend this LINQ List<>.Contains to work with any Property using Reflection?

I have the following snippet that I currently use to run a .Contains() with a list of Ids passed as a comma separated list from users. This code works perfectly and the data is filtered exactly as I want it to be:
// Handle id in() statements explicitly, dynamic expression can't parse them
var idIn = new Regex("id in ?(.*)", RegexOptions.IgnoreCase);
if (idIn.IsMatch(predicate))
{
Match list = new Regex(#"in ?\((.*)\)", RegexOptions.IgnoreCase).Match(predicate);
string ins = list.Groups[1].ToString();
// Split ins and store as List<>
List<int> splitValues = ins.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(i => Convert.ToInt32(i)).ToList();
return source.Where(u => splitValues.Contains(u.Id));
}
I want to be able to use this same idea, except with ANY property of the u object using reflection. I had a version of this working at some point, but cannot for the life of me figure out what has changed or why it stopped working. Here is the version I have that I cannot get working again:
Match splitIn = new Regex(#"([a-zA-Z0-9\.]*) IN ?\((.*)\)", RegexOptions.IgnoreCase).Match(predicate);
string property = splitIn.Groups[1].ToString();
string ins = splitIn.Groups[2].ToString().Trim(new[] {'\'', '"'}); // Trim off separator quotes
List<string> splitValues = ins.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList();
for (int i = 0; i < splitValues.Count; i++)
{
splitValues[i] = splitValues[i].Trim(new[] {'\'', '"'});
}
Expression<Func<U, bool>> contains = u => ListContainsProperty(u, splitValues, property);
return source.Where(contains);
private static bool ListContainsProperty<U>(U u, ICollection<string> list, string property)
{
string[] split = property.Split(new[] {"."}, StringSplitOptions.RemoveEmptyEntries);
object value = split.Aggregate<string, object>(u, (current, prop) => current.GetType().GetProperty(prop).GetValue(current, null));
return list.Contains(value.ToString());
}
As I said I once had SOME version of this working, but cannot figure out what has changed. Is there something blatantly obvious that I am missing that would help me get this functional again?
Edit: As far as I can tell the ListContainsProperty method is never actually running. Adding a "throw new Exception()" does nothing. I just get the full unfiltered list back.
I think the underlying problem is using "Expression"
you need to compile an Expression.
For example in your code
Expression<Func<U, bool>> contains = u => ListContainsProperty(u, splitValues, property);
is data and not a function. In order to use it you need to compile it.
Func<U, bool> compiled = contains.Compile();
"compiled" variable will call the "ListContainsProperty" method.

Counting results from a search string MVC 3?

I am using MVC3 and have done a search facility in my controller.I have used the model first approach , what I want to be able to allow the user to search for results that contain the given keyword(s) in the data.
If there are no matches to the search term then display an appropriate message.
If there are matching stories:
Display a message like “7 items match your search criteria: 'XXXXX'”
Any help would be much appreciated , Thanks
would it be something like this but with use of the ViewBag to display a message?.
if (!String.IsNullOrEmpty(SearchString))
News = News.Where(s => s.Headline.Count(SearchString));
}
You need to use string.Contains for partial string matching:
var matchingResults = News.Where(s => s.Headline.Contains(searchString));
int count = matchingResults.Count();
if(count == 0)
{
//no matches
}
else
{
//display message
}

Resources