public IQueryable<OutDoor> Search(IQueryable<OutDoor> OutDoors, SearchFilter searchFilter, out int totalHits) { if (OutDoors == null) { throw new ArgumentNullException("OutDoors"); } if (searchFilter == null) { throw new ArgumentNullException("searchFilter"); } if (searchFilter.Skip < 0) { throw new ArgumentOutOfRangeException("searchFilter"); } if (searchFilter.Take < 0) { throw new ArgumentOutOfRangeException("searchFilter"); } // For the given search term, find the keys that match. var keys = SearchCore(searchFilter, out totalHits); if (keys.Count == 0 || searchFilter.CountOnly) { return Enumerable.Empty<OutDoor>().AsQueryable(); } // Query the source for each of the keys that need to be taken. var results = OutDoors.Where(p => keys.Contains(p.MediaID)); // When querying the database, these keys are returned in no particular order. We use the original order of queries // and retrieve each of the OutDoors from the result in the same order. var lookup = results.ToDictionary(p => p.MediaID, p => p); return keys.Select(key => LookupOutDoor(lookup, key)) .Where(p => p != null) .AsQueryable(); }
private SearchFilter GetSearchFilter(string q, int sortOrder, int descending, int page, int pageSize) { var searchFilter = new SearchFilter { PageSize = pageSize, SearchTerm = q, Skip = (page - 1) * pageSize, // pages are 1-based. Take = pageSize }; searchFilter.SortProperty = (SortProperty)sortOrder; searchFilter.SortDirection = (SortDirection)descending; return searchFilter; }
public ActionResult GetSearchArea(float minX, float minY, float maxX, float maxY, int page = 1, int category = 0, int childcategory = 0, int price = 0) { var model = new ListSource(); var result = new List<HttpLinkItem>(); ListSearchItemViewModel query = new ListSearchItemViewModel(); query.MinX = minX; query.MinY = minY; query.MaxX = maxX; query.MaxY = maxY; if (category != 0) { query.MediaCode = category; if (childcategory != 0) { query.ChildMediaCode = childcategory; } } if (price != 0) { query.Price = price; } var pageSize = 10; int totalHits = 0; SearchFilter sf = new SearchFilter(); sf.PageSize = pageSize; sf.Skip = (page - 1) * pageSize; sf.Take = pageSize; sf.SortProperty = SortProperty.Published; sf.SortDirection = SortDirection.Descending; result = searchService.Search(query, sf, out totalHits); model.Items = result; model.TotalCount = totalHits; model.CurrentPage = page; model.PageSize = pageSize; return Json(model, JsonRequestBehavior.AllowGet); }
private static List<HttpLinkItem> SearchCore(ListSearchItemViewModel queryParams, SearchFilter searchFilter, out int totalHits) { if (!Directory.Exists(LuceneCommon.IndexDirectory)) { totalHits = 0; return new List<HttpLinkItem>(); } SortField sortField = GetSortField(searchFilter); int numRecords = searchFilter.Skip + searchFilter.Take; using (var directory = new LuceneFileSystem(LuceneCommon.IndexDirectory)) { var searcher = new IndexSearcher(directory, readOnly: true); var query = ParseQuery(queryParams, searchFilter); var results = searcher.Search(query, filter: null, n: numRecords, sort: new Sort(sortField)); var keys = results.ScoreDocs.Skip(searchFilter.Skip) .Select(c => GetMediaItem(searcher.Doc(c.Doc))) .ToList(); totalHits = results.TotalHits; searcher.Close(); return keys; } }
private static IList<int> SearchCore(SearchFilter searchFilter, out int totalHits) { if (!Directory.Exists(LuceneCommon.IndexDirectory)) { totalHits = 0; return new int[0]; } SortField sortField = GetSortField(searchFilter); int numRecords = searchFilter.Skip + searchFilter.Take; using (var directory = new LuceneFileSystem(LuceneCommon.IndexDirectory)) { var searcher = new IndexSearcher(directory, readOnly: true); var query = ParseQuery(searchFilter); var results = searcher.Search(query, filter: null, n: numRecords, sort: new Sort(sortField)); var keys = results.ScoreDocs.Skip(searchFilter.Skip) .Select(c => ParseKey(searcher.Doc(c.Doc).Get("MediaID"))) .ToList(); totalHits = results.TotalHits; searcher.Close(); return keys; } }
private static Query ParseQuery(ListSearchItemViewModel queryParams, SearchFilter searchFilter) { var combineQuery = new BooleanQuery(); #region 关键字查询构建 if (!String.IsNullOrWhiteSpace(searchFilter.SearchTerm)) { var fields = new[] { OutDoorIndexFields.Title, OutDoorIndexFields.Description, OutDoorIndexFields.AreaAtt, OutDoorIndexFields.MediaCateName, OutDoorIndexFields.CityName, OutDoorIndexFields.ProvinceName, OutDoorIndexFields.PMediaCateName, OutDoorIndexFields.FormatName, OutDoorIndexFields.PeriodName, OutDoorIndexFields.OwnerCateName }; var analyzer = new PanGuAnalyzer(); //var analyzer = new StandardAnalyzer(LuceneCommon.LuceneVersion); var queryParser = new MultiFieldQueryParser(LuceneCommon.LuceneVersion, fields, analyzer); var query = queryParser.Parse(searchFilter.SearchTerm); var conjuctionQuery = new BooleanQuery(); conjuctionQuery.Boost = 2.0f; var disjunctionQuery = new BooleanQuery(); disjunctionQuery.Boost = 0.1f; var wildCardQuery = new BooleanQuery(); wildCardQuery.Boost = 0.5f; var escapedSearchTerm = Escape(searchFilter.SearchTerm); var exactIdQuery = new TermQuery(new Term(OutDoorIndexFields.Title, escapedSearchTerm)); exactIdQuery.Boost = 2.5f; var wildCardIdQuery = new WildcardQuery(new Term(OutDoorIndexFields.Title, "*" + escapedSearchTerm + "*")); foreach (var term in GetSearchTerms(searchFilter.SearchTerm)) { var termQuery = queryParser.Parse(term); conjuctionQuery.Add(termQuery, Occur.MUST); disjunctionQuery.Add(termQuery, Occur.SHOULD); foreach (var field in fields) { var wildCardTermQuery = new WildcardQuery(new Term(field, term + "*")); wildCardTermQuery.Boost = 0.7f; wildCardQuery.Add(wildCardTermQuery, Occur.SHOULD); } } //关键查询 var keywordsQuery = conjuctionQuery.Combine(new Query[] { exactIdQuery, wildCardIdQuery, conjuctionQuery, disjunctionQuery, wildCardQuery }); combineQuery.Add(keywordsQuery, Occur.MUST); } #endregion #region 审核状态查询构建 var verifyStatus = NumericRangeQuery.NewIntRange(OutDoorIndexFields.Status, (int)OutDoorStatus.ShowOnline, 99, true, true); combineQuery.Add(verifyStatus, Occur.MUST); #endregion #region 省份查询 if (!String.IsNullOrEmpty(queryParams.Province) && queryParams.Province != "quanguo") { int ProvinceValue = EnumHelper.GetProvinceValue(queryParams.Province); var provinceQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.Province, ProvinceValue, ProvinceValue, true, true); combineQuery.Add(provinceQuery, Occur.MUST); } #endregion #region 城市查询 if (queryParams.City != 0) { var cityQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.City, queryParams.City, queryParams.City, true, true); combineQuery.Add(cityQuery, Occur.MUST); } #endregion #region 认证状态 if (queryParams.AuthStatus != 0) { var authStatusQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.AuthStatus, queryParams.AuthStatus, queryParams.AuthStatus, true, true); combineQuery.Add(authStatusQuery, Occur.MUST); } #endregion #region 经纬度搜索 if (queryParams.MinX != 0) { var latQuery = NumericRangeQuery.NewDoubleRange(OutDoorIndexFields.Lat, queryParams.MinX, queryParams.MaxX, true, true); var lngQuery = NumericRangeQuery.NewDoubleRange(OutDoorIndexFields.Lng, queryParams.MinY, queryParams.MaxY, true, true); combineQuery.Add(latQuery, Occur.MUST); combineQuery.Add(lngQuery, Occur.MUST); } #endregion #region 媒体类别查询 if (queryParams.MediaCode != 0) { var mediaCodeQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.PMediaCode, queryParams.MediaCode, queryParams.MediaCode, true, true); combineQuery.Add(mediaCodeQuery, Occur.MUST); } #endregion #region 媒体子类别查询 if (queryParams.ChildMediaCode != 0) { var ChildMediaCodeQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.MediaCode, queryParams.ChildMediaCode, queryParams.ChildMediaCode, true, true); combineQuery.Add(ChildMediaCodeQuery, Occur.MUST); } #endregion #region 媒体表现形式查询 if (queryParams.FormatCode != 0) { var FormatCodeCodeQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.FormatCode, queryParams.FormatCode, queryParams.FormatCode, true, true); combineQuery.Add(FormatCodeCodeQuery, Occur.MUST); } #endregion #region 媒体所有权查询 if (queryParams.OwnerCode != 0) { var OwnerCodeCodeQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.OwnerCode, queryParams.OwnerCode, queryParams.OwnerCode, true, true); combineQuery.Add(OwnerCodeCodeQuery, Occur.MUST); } #endregion #region 媒体购买周期查询 if (queryParams.PeriodCode != 0) { var PeriodCodeCodeQuery = NumericRangeQuery.NewIntRange(OutDoorIndexFields.PeriodCode, queryParams.PeriodCode, queryParams.PeriodCode, true, true); combineQuery.Add(PeriodCodeCodeQuery, Occur.MUST); } #endregion #region 媒体价格区间查询 if (queryParams.Price != 0) { var rangeValue = EnumHelper.GetPriceValue(queryParams.Price); var PriceQuery = NumericRangeQuery.NewDoubleRange(OutDoorIndexFields.Price, Convert.ToDouble(rangeValue.Min), Convert.ToDouble(rangeValue.Max), true, true); combineQuery.Add(PriceQuery, Occur.MUST); } #endregion return combineQuery; }
private static Query ParseQuery(SearchFilter searchFilter) { if (String.IsNullOrWhiteSpace(searchFilter.SearchTerm)) { return new MatchAllDocsQuery(); } var fields = new[] { "Title", "Description", "CompanyName", "AreaAtt", "MediaCateName", "CityName", "ProvinceName", "PMediaCateName", "FormatName", "PeriodName", "OwnerCateName" }; var analyzer = new PanGuAnalyzer(); //var analyzer = new StandardAnalyzer(LuceneCommon.LuceneVersion); var queryParser = new MultiFieldQueryParser(LuceneCommon.LuceneVersion, fields, analyzer); var query = queryParser.Parse(searchFilter.SearchTerm); // All terms in the multi-term query appear in at least one of the fields. var conjuctionQuery = new BooleanQuery(); conjuctionQuery.Boost = 2.0f; // Some terms in the multi-term query appear in at least one of the fields. var disjunctionQuery = new BooleanQuery(); disjunctionQuery.Boost = 0.1f; // Suffix wildcard search e.g. jquer* var wildCardQuery = new BooleanQuery(); wildCardQuery.Boost = 0.5f; //// Escape the entire term we use for exact searches. var escapedSearchTerm = Escape(searchFilter.SearchTerm); var exactIdQuery = new TermQuery(new Term("Title", escapedSearchTerm)); exactIdQuery.Boost = 2.5f; var wildCardIdQuery = new WildcardQuery(new Term("Title", "*" + escapedSearchTerm + "*")); foreach (var term in GetSearchTerms(searchFilter.SearchTerm)) { var termQuery = queryParser.Parse(term); conjuctionQuery.Add(termQuery, Occur.MUST); disjunctionQuery.Add(termQuery, Occur.SHOULD); foreach (var field in fields) { var wildCardTermQuery = new WildcardQuery(new Term(field, term + "*")); wildCardTermQuery.Boost = 0.7f; wildCardQuery.Add(wildCardTermQuery, Occur.SHOULD); } } var combinedQuery = conjuctionQuery.Combine(new Query[] { exactIdQuery, wildCardIdQuery, conjuctionQuery, disjunctionQuery, wildCardQuery }); if (searchFilter.SortProperty == SortProperty.Hit) { // If searching by relevance, boost scores by download count. var downloadCountBooster = new FieldScoreQuery("Hit", FieldScoreQuery.Type.INT); return new CustomScoreQuery(combinedQuery, downloadCountBooster); } return combinedQuery; }
private static SortField GetSortField(SearchFilter searchFilter) { switch (searchFilter.SortProperty) { case SortProperty.Hit: return new SortField(OutDoorIndexFields.Hit, SortField.INT, reverse: searchFilter.SortDirection.Equals(SortDirection.Descending)); case SortProperty.Price: return new SortField(OutDoorIndexFields.Price, SortField.DOUBLE, reverse: searchFilter.SortDirection.Equals(SortDirection.Descending)); case SortProperty.Published: return new SortField(OutDoorIndexFields.Published, SortField.LONG, reverse: searchFilter.SortDirection.Equals(SortDirection.Descending)); } return SortField.FIELD_SCORE; }
public List<HttpLinkItem> Search(ListSearchItemViewModel queryParams, SearchFilter searchFilter, out int totalHits) { if (searchFilter == null) { throw new ArgumentNullException("searchFilter"); } if (searchFilter.Skip < 0) { throw new ArgumentOutOfRangeException("searchFilter"); } if (searchFilter.Take < 0) { throw new ArgumentOutOfRangeException("searchFilter"); } var searchResults = SearchCore(queryParams, searchFilter, out totalHits); return searchResults; }