public virtual Filter GetFilter(XmlElement e) { string field = DOMUtils.GetAttributeWithInheritanceOrFail(e, "fieldName"); string lowerTerm = DOMUtils.GetAttributeOrFail(e, "lowerTerm"); string upperTerm = DOMUtils.GetAttributeOrFail(e, "upperTerm"); bool lowerInclusive = DOMUtils.GetAttribute(e, "includeLower", true); bool upperInclusive = DOMUtils.GetAttribute(e, "includeUpper", true); int precisionStep = DOMUtils.GetAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT); string type = DOMUtils.GetAttribute(e, "type", "int"); try { Filter filter; if (type.Equals("int", StringComparison.OrdinalIgnoreCase)) { filter = NumericRangeFilter.NewIntRange(field, precisionStep, Convert.ToInt32(lowerTerm), Convert.ToInt32(upperTerm), lowerInclusive, upperInclusive); } else if (type.Equals("long", StringComparison.OrdinalIgnoreCase)) { filter = NumericRangeFilter.NewLongRange(field, precisionStep, Convert .ToInt64(lowerTerm), Convert.ToInt64(upperTerm), lowerInclusive, upperInclusive); } else if (type.Equals("double", StringComparison.OrdinalIgnoreCase)) { filter = NumericRangeFilter.NewDoubleRange(field, precisionStep, Convert .ToDouble(lowerTerm), Convert.ToDouble(upperTerm), lowerInclusive, upperInclusive); } else if (type.Equals("float", StringComparison.OrdinalIgnoreCase)) { filter = NumericRangeFilter.NewFloatRange(field, precisionStep, Convert .ToSingle(lowerTerm), Convert.ToSingle(upperTerm), lowerInclusive, upperInclusive); } else { throw new ParserException("type attribute must be one of: [long, int, double, float]"); } return(filter); } catch (FormatException nfe) { if (strictMode) { throw new ParserException("Could not parse lowerTerm or upperTerm into a number", nfe); } return(NO_MATCH_FILTER); } }
/// <summary> /// 通过类型来获取 /// </summary> /// <param name="property"></param> /// <param name="min"></param> /// <param name="max"></param> /// <returns></returns> public static Filter GetNumberFilter(PropertyInfo property, double min, double max) { if (property.PropertyType == typeof(double) || property.PropertyType == typeof(decimal)) { return(NumericRangeFilter.NewDoubleRange(property.Name, min, max, true, true)); } else if (property.PropertyType == typeof(float)) { return(NumericRangeFilter.NewFloatRange(property.Name, (float)min, (float)max, true, true)); } else if (property.PropertyType == typeof(int)) { return(NumericRangeFilter.NewIntRange(property.Name, (int)min, (int)max, true, true)); } else { return(null); } }
/// <summary> /// 分页获取商品信息数据 /// </summary> /// <param name="queryString"></param> /// <param name="pageIndex">第一页为1</param> /// <param name="pageSize"></param> /// <param name="totalCount"></param> /// <returns></returns> public List <Commodity> QueryIndexPage(string queryString, int pageIndex, int pageSize, out int totalCount, string priceFilter, string priceOrderBy) { totalCount = 0; IndexSearcher searcher = null; try { List <Commodity> ciList = new List <Commodity>(); FSDirectory dir = FSDirectory.Open(StaticConstant.IndexPath); searcher = new IndexSearcher(dir); Analyzer analyzer = new PanGuAnalyzer(); //--------------------------------------这里配置搜索条件 QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "title", analyzer); Query query = parser.Parse(queryString); pageIndex = Math.Max(1, pageIndex);//索引从1开始 int startIndex = (pageIndex - 1) * pageSize; int endIndex = pageIndex * pageSize; NumericRangeFilter <float> numPriceFilter = null; if (!string.IsNullOrWhiteSpace(priceFilter)) { bool isContainStart = priceFilter.StartsWith("["); bool isContainEnd = priceFilter.EndsWith("]"); string[] floatArray = priceFilter.Replace("[", "").Replace("]", "").Replace("{", "").Replace("}", "").Split(','); float start = 0; float end = 0; if (!float.TryParse(floatArray[0], out start) || !float.TryParse(floatArray[1], out end)) { throw new Exception("Wrong priceFilter"); } numPriceFilter = NumericRangeFilter.NewFloatRange("price", start, end, isContainStart, isContainEnd); } Sort sort = new Sort(); if (!string.IsNullOrWhiteSpace(priceOrderBy)) { SortField sortField = new SortField("price", SortField.FLOAT, priceOrderBy.EndsWith("asc", StringComparison.CurrentCultureIgnoreCase)); sort.SetSort(sortField); } TopDocs docs = searcher.Search(query, numPriceFilter, 10000, sort); //TopDocs docs = searcher.Search(query, null, 10000); totalCount = docs.TotalHits; //PrintScores(docs, startIndex, endIndex, searcher); for (int i = startIndex; i < endIndex && i < totalCount; i++) { Document doc = searcher.Doc(docs.ScoreDocs[i].Doc); ciList.Add(DocumentToCommodityInfo(doc)); } return(ciList); } finally { if (searcher != null) { searcher.Dispose(); } } }
public virtual void TestRandomFloats() { Directory dir = NewDirectory(); RandomIndexWriter w = new RandomIndexWriter(Random(), dir, Similarity, TimeZone); int numDocs = AtLeast(1000); float[] values = new float[numDocs]; float minValue = float.PositiveInfinity; float maxValue = float.NegativeInfinity; for (int i = 0; i < numDocs; i++) { Document doc = new Document(); float v = Random().NextFloat(); values[i] = v; doc.Add(new FloatDocValuesField("field", v)); doc.Add(new FloatField("field", v, Field.Store.NO)); w.AddDocument(doc); minValue = Math.Min(minValue, v); maxValue = Math.Max(maxValue, v); } IndexReader r = w.Reader; IndexSearcher s = NewSearcher(r); FacetsConfig config = new FacetsConfig(); int numIters = AtLeast(10); for (int iter = 0; iter < numIters; iter++) { if (VERBOSE) { Console.WriteLine("TEST: iter=" + iter); } int numRange = TestUtil.NextInt(Random(), 1, 5); DoubleRange[] ranges = new DoubleRange[numRange]; int[] expectedCounts = new int[numRange]; float minAcceptedValue = float.PositiveInfinity; float maxAcceptedValue = float.NegativeInfinity; if (VERBOSE) { Console.WriteLine("TEST: " + numRange + " ranges"); } for (int rangeID = 0; rangeID < numRange; rangeID++) { double min; if (rangeID > 0 && Random().Next(10) == 7) { // Use an existing boundary: DoubleRange prevRange = ranges[Random().Next(rangeID)]; if (Random().NextBoolean()) { min = prevRange.Min; } else { min = prevRange.Max; } } else { min = Random().NextDouble(); } double max; if (rangeID > 0 && Random().Next(10) == 7) { // Use an existing boundary: DoubleRange prevRange = ranges[Random().Next(rangeID)]; if (Random().NextBoolean()) { max = prevRange.Min; } else { max = prevRange.Max; } } else { max = Random().NextDouble(); } if (min > max) { double x = min; min = max; max = x; } // Must truncate to float precision so that the // drill-down counts (which use NRQ.newFloatRange) // are correct: min = (float)min; max = (float)max; bool minIncl; bool maxIncl; if (min == max) { minIncl = true; maxIncl = true; } else { minIncl = Random().NextBoolean(); maxIncl = Random().NextBoolean(); } ranges[rangeID] = new DoubleRange("r" + rangeID, min, minIncl, max, maxIncl); if (VERBOSE) { Console.WriteLine("TEST: range " + rangeID + ": " + ranges[rangeID]); } // Do "slow but hopefully correct" computation of // expected count: for (int i = 0; i < numDocs; i++) { bool accept = true; if (minIncl) { accept &= values[i] >= min; } else { accept &= values[i] > min; } if (maxIncl) { accept &= values[i] <= max; } else { accept &= values[i] < max; } if (VERBOSE) { Console.WriteLine("TEST: check doc=" + i + " val=" + values[i] + " accept=" + accept); } if (accept) { expectedCounts[rangeID]++; minAcceptedValue = Math.Min(minAcceptedValue, values[i]); maxAcceptedValue = Math.Max(maxAcceptedValue, values[i]); } } } FacetsCollector sfc = new FacetsCollector(); s.Search(new MatchAllDocsQuery(), sfc); Filter fastMatchFilter; if (Random().NextBoolean()) { if (Random().NextBoolean()) { fastMatchFilter = NumericRangeFilter.NewFloatRange("field", minValue, maxValue, true, true); } else { fastMatchFilter = NumericRangeFilter.NewFloatRange("field", minAcceptedValue, maxAcceptedValue, true, true); } } else { fastMatchFilter = null; } ValueSource vs = new FloatFieldSource("field"); Facets facets = new DoubleRangeFacetCounts("field", vs, sfc, fastMatchFilter, ranges); FacetResult result = facets.GetTopChildren(10, "field"); Assert.AreEqual(numRange, result.LabelValues.Length); for (int rangeID = 0; rangeID < numRange; rangeID++) { if (VERBOSE) { Console.WriteLine("TEST: verify range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); } LabelAndValue subNode = result.LabelValues[rangeID]; Assert.AreEqual("r" + rangeID, subNode.label); Assert.AreEqual(expectedCounts[rangeID], (int)subNode.value); DoubleRange range = ranges[rangeID]; // Test drill-down: DrillDownQuery ddq = new DrillDownQuery(config); if (Random().NextBoolean()) { if (Random().NextBoolean()) { ddq.Add("field", NumericRangeFilter.NewFloatRange("field", (float)range.Min, (float)range.Max, range.MinInclusive, range.MaxInclusive)); } else { ddq.Add("field", NumericRangeQuery.NewFloatRange("field", (float)range.Min, (float)range.Max, range.MinInclusive, range.MaxInclusive)); } } else { ddq.Add("field", range.GetFilter(fastMatchFilter, vs)); } Assert.AreEqual(expectedCounts[rangeID], s.Search(ddq, 10).TotalHits); } } IOUtils.Close(w, r, dir); }