public virtual void TestFarsiRangeQueryCollating(Analyzer analyzer, BytesRef firstBeg, BytesRef firstEnd, BytesRef secondBeg, BytesRef secondEnd) { Directory dir = NewDirectory(); IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, analyzer)); Document doc = new Document(); // Unicode order would include U+0633 in [ U+062F - U+0698 ], but Farsi // orders the U+0698 character before the U+0633 character, so the single // index Term below should NOT be returned by a TermRangeQuery with a Farsi // Collator (or an Arabic one for the case when Farsi is not supported). doc.Add(new TextField("content", "\u0633\u0627\u0628", Field.Store.YES)); writer.AddDocument(doc); writer.Dispose(); IndexReader reader = DirectoryReader.Open(dir); IndexSearcher searcher = new IndexSearcher(reader); Query query = new TermRangeQuery("content", firstBeg, firstEnd, true, true); ScoreDoc[] hits = searcher.Search(query, null, 1000).ScoreDocs; Assert.AreEqual(0, hits.Length, "The index Term should not be included."); query = new TermRangeQuery("content", secondBeg, secondEnd, true, true); hits = searcher.Search(query, null, 1000).ScoreDocs; Assert.AreEqual(1, hits.Length, "The index Term should be included."); reader.Dispose(); dir.Dispose(); }
public virtual void TestFarsiTermRangeQuery(Analyzer analyzer, BytesRef firstBeg, BytesRef firstEnd, BytesRef secondBeg, BytesRef secondEnd) { Directory farsiIndex = NewDirectory(); IndexWriter writer = new IndexWriter(farsiIndex, new IndexWriterConfig(TEST_VERSION_CURRENT, analyzer)); Document doc = new Document(); doc.Add(new TextField("content", "\u0633\u0627\u0628", Field.Store.YES)); doc.Add(new StringField("body", "body", Field.Store.YES)); writer.AddDocument(doc); writer.Dispose(); IndexReader reader = DirectoryReader.Open(farsiIndex); IndexSearcher search = NewSearcher(reader); // Unicode order would include U+0633 in [ U+062F - U+0698 ], but Farsi // orders the U+0698 character before the U+0633 character, so the single // index Term below should NOT be returned by a TermRangeQuery // with a Farsi Collator (or an Arabic one for the case when Farsi is // not supported). Query csrq = new TermRangeQuery("content", firstBeg, firstEnd, true, true); ScoreDoc[] result = search.Search(csrq, null, 1000).ScoreDocs; Assert.AreEqual(0, result.Length, "The index Term should not be included."); csrq = new TermRangeQuery("content", secondBeg, secondEnd, true, true); result = search.Search(csrq, null, 1000).ScoreDocs; Assert.AreEqual(1, result.Length, "The index Term should be included."); reader.Dispose(); farsiIndex.Dispose(); }
/// <summary> /// Builds the query. /// </summary> /// <param name="criteria">The criteria.</param> /// <returns></returns> public override object BuildQuery(ISearchCriteria criteria) { var builder = base.BuildQuery(criteria) as QueryBuilder; var query = builder.Query as BooleanQuery; var analyzer = new StandardAnalyzer(u.Version.LUCENE_30); if (criteria is CatalogItemSearchCriteria) { var c = criteria as CatalogItemSearchCriteria; var datesFilterStart = new TermRangeQuery( "startdate", c.StartDateFrom.HasValue ? DateTools.DateToString(c.StartDateFrom.Value, DateTools.Resolution.SECOND) : null, DateTools.DateToString(c.StartDate, DateTools.Resolution.SECOND), false, true); query.Add(datesFilterStart, Occur.MUST); if (c.EndDate.HasValue) { var datesFilterEnd = new TermRangeQuery( "enddate", DateTools.DateToString(c.EndDate.Value, DateTools.Resolution.SECOND), null, true, false); query.Add(datesFilterEnd, Occur.MUST); } if (c.Outlines != null && c.Outlines.Count > 0) { AddQuery("__outline", query, c.Outlines); } query.Add(new TermQuery(new Term("__hidden", "false")), Occur.MUST); if (!String.IsNullOrEmpty(c.Catalog)) { AddQuery("catalog", query, c.Catalog); } // Add search if (!String.IsNullOrEmpty(c.SearchPhrase)) { if (c.IsFuzzySearch) { var keywords = c.SearchPhrase.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); //var keywords = Regex.Split(c.SearchPhrase, @"\s+"); var searchPhrase = string.Empty; searchPhrase = keywords.Aggregate( searchPhrase, (current, keyword) => current + String.Format("{0}~{1}", keyword.Replace("~", ""), c.FuzzyMinSimilarity)); var parser = new QueryParser(u.Version.LUCENE_30, "__content", analyzer) { DefaultOperator = QueryParser .Operator.AND }; var searchQuery = parser.Parse(searchPhrase); query.Add(searchQuery, Occur.MUST); } else { var parser = new QueryParser(u.Version.LUCENE_30, "__content", analyzer) { DefaultOperator = QueryParser .Operator.AND }; var searchQuery = parser.Parse(c.SearchPhrase); query.Add(searchQuery, Occur.MUST); } } } else if (criteria is OrderSearchCriteria) { var c = criteria as OrderSearchCriteria; if (!String.IsNullOrEmpty(c.CustomerId)) { AddQuery("customerid", query, c.CustomerId); } } return builder; }
/// <summary> /// Adds a range clause to this instance /// </summary> /// <remarks>Adds a range to search into the query</remarks> /// <remarks>All values specified in the startTerm are applied to this entire clause</remarks> /// <param name="startTerm">Starting half of the range to add to this query</param> /// <param name="endValue">Ending half of the range to add to this query</param> /// <param name="occurrence">Defines how the term is added to this query</param> /// <param name="includeStartValue">Determines if the starting term is included or excluded in the search results</param> /// <param name="includeEndValue">Determines if the ending term is included or excluded in the search results</param> public void AddTermRangeClause(SearchTerm startTerm, string endValue, ClauseOccurrence occurrence, bool includeStartValue, bool includeEndValue) { if (startTerm == null) throw new ArgumentNullException("startTerm", "startTerm cannot be null"); if (string.IsNullOrEmpty(endValue)) throw new ArgumentNullException("endValue", "endValue cannot be null or empty"); IncrementTotalClauses(1); TermRangeQuery rangeQuery = new TermRangeQuery(startTerm.FieldName, startTerm.FieldValue, endValue, includeStartValue, includeEndValue); rangeQuery.SetBoost(startTerm.Boost); this.luceneQuery.Add(rangeQuery, TypeConverter.ConvertToLuceneClauseOccurrence(occurrence)); rangeQuery = null; }
/// <summary> /// Creates the query. /// </summary> /// <param name="field">The field.</param> /// <param name="value">The value.</param> /// <returns></returns> public static Query CreateQuery(string field, RangeFilterValue value) { object lowerbound = value.Lower; object upperbound = value.Upper; var query = new TermRangeQuery( field, ConvertToSearchable(lowerbound), ConvertToSearchable(upperbound), true, false); return query; }
/// <summary> /// Extracts all <see cref="MultiTermQuery"/>s for <paramref name="field"/>, and returns equivalent /// automata that will match terms. /// </summary> internal static CharacterRunAutomaton[] ExtractAutomata(Query query, string field) { List <CharacterRunAutomaton> list = new List <CharacterRunAutomaton>(); if (query is BooleanQuery) { BooleanClause[] clauses = ((BooleanQuery)query).GetClauses(); foreach (BooleanClause clause in clauses) { if (!clause.IsProhibited) { list.AddAll(Arrays.AsList(ExtractAutomata(clause.Query, field))); } } } else if (query is DisjunctionMaxQuery) { foreach (Query sub in ((DisjunctionMaxQuery)query).Disjuncts) { list.AddAll(Arrays.AsList(ExtractAutomata(sub, field))); } } else if (query is SpanOrQuery) { foreach (Query sub in ((SpanOrQuery)query).GetClauses()) { list.AddAll(Arrays.AsList(ExtractAutomata(sub, field))); } } else if (query is SpanNearQuery) { foreach (Query sub in ((SpanNearQuery)query).GetClauses()) { list.AddAll(Arrays.AsList(ExtractAutomata(sub, field))); } } else if (query is SpanNotQuery) { list.AddAll(Arrays.AsList(ExtractAutomata(((SpanNotQuery)query).Include, field))); } else if (query is SpanPositionCheckQuery) { list.AddAll(Arrays.AsList(ExtractAutomata(((SpanPositionCheckQuery)query).Match, field))); } else if (query is ISpanMultiTermQueryWrapper) { list.AddAll(Arrays.AsList(ExtractAutomata(((ISpanMultiTermQueryWrapper)query).WrappedQuery, field))); } else if (query is AutomatonQuery) { AutomatonQuery aq = (AutomatonQuery)query; if (aq.Field.Equals(field)) { list.Add(new CharacterRunAutomatonToStringAnonymousHelper(aq.Automaton, () => aq.ToString())); } } else if (query is PrefixQuery) { PrefixQuery pq = (PrefixQuery)query; Term prefix = pq.Prefix; if (prefix.Field.Equals(field)) { list.Add(new CharacterRunAutomatonToStringAnonymousHelper( BasicOperations.Concatenate(BasicAutomata.MakeString(prefix.Text()), BasicAutomata.MakeAnyString()), () => pq.ToString())); } } else if (query is FuzzyQuery) { FuzzyQuery fq = (FuzzyQuery)query; if (fq.Field.Equals(field)) { string utf16 = fq.Term.Text(); int[] termText = new int[utf16.CodePointCount(0, utf16.Length)]; for (int cp, i = 0, j = 0; i < utf16.Length; i += Character.CharCount(cp)) { termText[j++] = cp = utf16.CodePointAt(i); } int termLength = termText.Length; int prefixLength = Math.Min(fq.PrefixLength, termLength); string suffix = UnicodeUtil.NewString(termText, prefixLength, termText.Length - prefixLength); LevenshteinAutomata builder = new LevenshteinAutomata(suffix, fq.Transpositions); Automaton automaton = builder.ToAutomaton(fq.MaxEdits); if (prefixLength > 0) { Automaton prefix = BasicAutomata.MakeString(UnicodeUtil.NewString(termText, 0, prefixLength)); automaton = BasicOperations.Concatenate(prefix, automaton); } list.Add(new CharacterRunAutomatonToStringAnonymousHelper(automaton, () => fq.ToString())); } } else if (query is TermRangeQuery) { TermRangeQuery tq = (TermRangeQuery)query; if (tq.Field.Equals(field)) { // this is *not* an automaton, but its very simple list.Add(new SimpleCharacterRunAutomatonAnonymousHelper(BasicAutomata.MakeEmpty(), tq)); } } return(list.ToArray(/*new CharacterRunAutomaton[list.size()]*/)); }
/// <summary> /// 搜索 /// </summary> /// <param name="query"></param> /// <param name="price">100-300</param> /// <param name="startDate"></param> /// <param name="endDate"></param> /// <returns></returns> public List <GoodsAlias> SearchGoods(string query, string price, DateTime?startDate, DateTime?endDate) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start();//计时开始 var ver = Lucene.Net.Util.Version.LUCENE_30; Directory indexDirectory = FSDirectory.Open(new System.IO.DirectoryInfo(SearchIndexPath)); Analyzer analyzer = new PanGuAnalyzer(); IndexSearcher searcher = null; List <GoodsAlias> goodses = new List <GoodsAlias>(); int recCount = 0; bool isHasQuery = !string.IsNullOrEmpty(query), isHasPrice = !string.IsNullOrEmpty(price), isHasStartDate = startDate.HasValue, isHasEndDate = endDate.HasValue; try { searcher = new IndexSearcher(indexDirectory, true); BooleanQuery booleanQuery = new BooleanQuery(); if (isHasQuery) { var title = GetKeyWordsSplitBySpace(query); Query query3 = new QueryParser(ver, "title", analyzer).Parse(title); booleanQuery.Add(query3, Occur.MUST); } //按价格范围搜索(对数字搜索) if (isHasPrice) { string[] prices = price.Split(new char[] { '-' }); float min = float.Parse(prices[0]); float max = prices.Length < 2 ? 10000000000.00f : float.Parse(prices[1]); Query query4 = NumericRangeQuery.NewFloatRange("price", min, max, true, true); booleanQuery.Add(query4, Occur.MUST); } //按日期范围搜索(对日期搜索) if (isHasStartDate || isHasEndDate) { string mindate = isHasStartDate ? startDate.Value.ToString("yyyy-MM-dd") : DateTime.MinValue.ToString("yyyy-MM-dd"); string maxdate = isHasEndDate ? endDate.Value.ToString("yyyy-MM-dd") : DateTime.Today.ToString("yyyy-MM-dd"); Query query5 = new TermRangeQuery("createdon", mindate, maxdate, true, true); booleanQuery.Add(query5, Occur.MUST); } //如果没有查询关键字则显示全部的数据 if (!isHasQuery && !isHasPrice && !isHasStartDate && !isHasEndDate) { Query query6 = new TermQuery(new Term("all", "all")); booleanQuery.Add(query6, Occur.MUST); } //执行搜索,获取查询结果集对象 TopDocs topDocs = searcher.Search(booleanQuery, null, 100); recCount = topDocs.TotalHits; //获取命中的文档个数 ScoreDoc[] hits = topDocs.ScoreDocs; //获取命中的文档信息对象 stopWatch.Stop(); //计时停止 foreach (var item in hits) { goodses.Add(new GoodsAlias { Id = new Guid(searcher.Doc(item.Doc).Get("id")), Name = searcher.Doc(item.Doc).Get("title"), Pics = searcher.Doc(item.Doc).Get("pics"), Price = Convert.ToDecimal(searcher.Doc(item.Doc).Get("price")), OriginalPrice = Convert.ToDecimal(searcher.Doc(item.Doc).Get("originalprice")), Benevolence = Convert.ToDecimal(searcher.Doc(item.Doc).Get("benevolence")), SellOut = Convert.ToInt32(searcher.Doc(item.Doc).Get("sellout")), Rate = Convert.ToSingle(searcher.Doc(item.Doc).Get("rate")), CreatedOn = Convert.ToDateTime(searcher.Doc(item.Doc).Get("createdon")) }); } } catch (Exception) { throw; } finally { if (searcher != null) { searcher.Dispose(); } } return(goodses); }