팜의 목록을 반환하는 토큰 화 된 쿼리 문자열을 기반으로 필터링 시스템을 만드는 방법을 찾고 있습니다.Linq 및 EF로 필터링 된 토큰 화 된 검색 결과
필터링 메커니즘은 결과를 반환하기 위해 임의의 순서로 토큰을 제공 할만큼 충분히 유연 할 수 있기를 바랍니다. 검색
규칙은 다음과 같이 될 것이다 :
상태 : WA 작물 : 바나나
이
자르기 banana
와 WA
나에게 모든 농장의 필터링 된 목록을 제공합니다.
작물 : 바나나 상태 :
WA
동일한 결과를 반환한다.도시 : 알바니 작물 :
바나나
자르기banana
와
Albany
나에게 모든 농장의 필터링 된 목록을 제공합니다.
제공된 각 값은 공백으로 구분 된 값을 그룹화 할 수 있도록 따옴표로 묶을 수 있습니다. 예컨대
도시 "마운트 바커"작물 : 바나나
자르기 banana
와 Mount Barker
나에게 모든 농장의 필터링 된 목록을 제공합니다.
토큰없는 쿼리는 팜 Details
속성 내에서 여러 단어 쿼리를 결합하는 인용 부호로 팜 목록을 다시 반환합니다.
--------------------------------------- EDIT ------ --------------------------------------
현재 사용하는 술어를 사용하는 검색 시스템이 코딩되어 있습니다. 다음과 같이 그것은 길고 (미안하다) 나는 이것이 일종의 영혼에 의해 리팩터링 될 수 있기를 희망하지만 첫 번째 시도이다. 사전에
많은 감사 :
public ActionResult Search(string query, int? page)
{
IQueryable<Farm> farms = this.ReadOnlySession.All<Farm>();
if (!String.IsNullOrWhiteSpace(query))
{
// http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder
var predicate = PredicateBuilder.True<Farm>();
// We want to replace the spaces in quoted values here so we can split by space later.
// http://stackoverflow.com/questions/2148587/regex-quoted-string-with-escaped-quotes-in-c
Regex quoted = new Regex(@"""[^""\\]*(?:\\.[^""\\]*)*""");
foreach (var match in quoted.Matches(query))
{
query = query.Replace(match.ToString(), match.ToString().Replace(' ', '-'));
}
// Tidy up the query to remove "".
string[] splitQuery = HttpUtility.UrlDecode(query).Replace("\"", "").Split(' ');
Dictionary<string, string> tokenDictionary = new Dictionary<string, string>();
// Loop through our string[] and create a dictionary. Guids used to allow multiple keys
// of the same value.
Parallel.ForEach(splitQuery, subQuery =>
{
string[] tempArray = subQuery.Split(':');
if (tempArray.Length == 2)
{
tokenDictionary.Add(String.Format("{0}:{1}", tempArray[0], Guid.NewGuid()), tempArray[1]);
}
else
{
tokenDictionary.Add(String.Format("description:{0}", Guid.NewGuid()), subQuery);
}
});
// Loop through the dictionary and create our predicate.
foreach (KeyValuePair<string, string> item in tokenDictionary)
{
string value = item.Value.Replace('-', ' ');
string key = item.Key.Split(':')[0].ToUpperInvariant();
switch (key)
{
case "CROP":
value = Utilities.CreateSlug(value, OzFarmGuideConfig.RemoveDiacritics);
predicate = predicate.And(x => x.Crops.Any(y => value.Equals(y.Slug, StringComparison.OrdinalIgnoreCase)));
break;
case "STATE":
predicate = predicate.And(x => value.Equals(x.City.State.Name, StringComparison.OrdinalIgnoreCase));
break;
case "CITY":
value = Utilities.CreateSlug(value, OzFarmGuideConfig.RemoveDiacritics);
predicate = predicate.And(x => value.Equals(x.City.Slug, StringComparison.OrdinalIgnoreCase));
break;
default:
predicate = predicate.And(x => !String.IsNullOrWhiteSpace(x.Details) && x.Details.Contains(value));
break;
}
}
farms = farms.Where(predicate).OrderByDescending(x => x.Rating)
.ThenByDescending(x => x.RatingVotes);
PagedList<Farm> pagedFarms = new PagedList<Farm>(farms, page.HasValue ? page.Value - 1 : 0, 5);
return View(pagedFarms);
}
else
{
PagedList<Farm> pagedFarms = null;
return View(pagedFarms);
}
}
저는 실제로! StringIsNullOrWhitespace 호출로 문제를 해결했지만 코드 주석을 업데이트하지 않았습니다. 청소부처럼 보이지만 제안을 확인하겠습니다. 나는 지금 내가 바보 같은 짓을하고 있는지 정말보고 싶다. 고마워! –
오,'세부 사항'문자열입니까? 그렇다면 내 제안이 정확하지 않을 수 있습니다. 나는 그것이 어떤 종류의 콜렉션 (리스트)이라고 생각했다. – ckittel
그래 .... 죄송합니다. 분명하지 않다면. 나는 지금 술어로 일하는 데 어려움을 겪고있다. 어떤 이유로 내가 그들을 사용할 때 모든 농장이 반환됩니다. –