示例#1
0
        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();
        }
示例#2
0
        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()]*/));
        }
示例#7
0
        /// <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);
        }