protected virtual Lucene.Net.Search.Query VisitWithinRadius(WithinRadiusNode node, LuceneQueryMapperState mappingState) { SpatialContext ctx = SpatialContext.GEO; var strategy = new PointVectorStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName); if (node.Latitude is double && node.Longitude is double && node.Radius is double) { var distance = DistanceUtils.Dist2Degrees((double)node.Radius, DistanceUtils.EARTH_MEAN_RADIUS_MI); Circle circle = ctx.MakeCircle((double)node.Longitude, (double)node.Latitude, distance); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, circle); var dq = strategy.MakeQuery(spatialArgs); DistanceReverseValueSource valueSource = new DistanceReverseValueSource(strategy, circle.GetCenter(), distance); ValueSourceFilter vsf = new ValueSourceFilter(new QueryWrapperFilter(dq), valueSource, 0, distance); var filteredSpatial = new FilteredQuery(new MatchAllDocsQuery(), vsf); Lucene.Net.Search.Query spatialRankingQuery = new FunctionQuery(valueSource); BooleanQuery bq = new BooleanQuery(); bq.Add(filteredSpatial, Occur.MUST); bq.Add(spatialRankingQuery, Occur.MUST); return(bq); } throw new NotSupportedException("Wrong parameters type, Radius, latitude and longitude must be of type double"); }
public DistanceReverseValueSource(PointVectorStrategy strategy, Point from, double max) : base(strategy, from) { this.strategy = strategy; this.from = from; this.max = max; }
protected virtual Lucene.Net.Search.Query VisitWithinRadius(WithinRadiusNode node, LuceneQueryMapperState mappingState) { SpatialContext ctx = SpatialContext.GEO; var strategy = new PointVectorStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName); if (node.Latitude is double && node.Longitude is double && node.Radius is double) { var distance = DistanceUtils.Dist2Degrees((double)node.Radius, DistanceUtils.EARTH_MEAN_RADIUS_MI); Circle circle = ctx.MakeCircle((double)node.Longitude, (double)node.Latitude, distance); var spatialArgs = new SpatialArgs(SpatialOperation.IsWithin, circle); var dq = strategy.MakeQuery(spatialArgs); DistanceReverseValueSource valueSource = new DistanceReverseValueSource(strategy, circle.GetCenter(), distance); ValueSourceFilter vsf = new ValueSourceFilter(new QueryWrapperFilter(dq), valueSource, 0, distance); var filteredSpatial = new FilteredQuery(new MatchAllDocsQuery(), vsf); mappingState.FilterQuery = filteredSpatial; Lucene.Net.Search.Query spatialRankingQuery = new FunctionQuery(valueSource); Random r = new Random(DateTime.Now.Millisecond); var randomNumber = r.Next(10000101, 11000101); Lucene.Net.Search.Query dummyQuery = Lucene.Net.Search.NumericRangeQuery.NewIntRange("__smallcreateddate", randomNumber, Int32.Parse(DateTime.Now.ToString("yyyyMMdd")), true, true); BooleanQuery bq = new BooleanQuery(); bq.Add(filteredSpatial, Occur.MUST); bq.Add(spatialRankingQuery, Occur.MUST); bq.Add(dummyQuery, Occur.SHOULD); return(bq); } throw new NotSupportedException("Wrong parameters type, Radius, latitude and longitude must be of type double"); }
//@ParametersFactory public static IList <Object[]> Parameters() { List <Object[]> ctorArgs = new List <object[]>(); SpatialContext ctx = SpatialContext.GEO; SpatialPrefixTree grid; SpatialStrategy strategy; grid = new GeohashPrefixTree(ctx, 12); strategy = new RecursivePrefixTreeStrategy(grid, "recursive_geohash"); ctorArgs.Add(new Object[] { new Param(strategy) }); grid = new QuadPrefixTree(ctx, 25); strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad"); ctorArgs.Add(new Object[] { new Param(strategy) }); grid = new GeohashPrefixTree(ctx, 12); strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash"); ctorArgs.Add(new Object[] { new Param(strategy) }); strategy = new PointVectorStrategy(ctx, "pointvector"); ctorArgs.Add(new Object[] { new Param(strategy) }); return(ctorArgs); }
public DistranceCustomScoreProvider(IndexReader reader, PointVectorStrategy strategy, Point origin) : base(reader) { _strategy = strategy; _originPt = origin; _currentReaderValuesX = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetDoubles(reader, _strategy.GetFieldNameX()); _currentReaderValuesY = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetDoubles(reader, _strategy.GetFieldNameY()); }
public static TopDocs DistranceScore_PointVectorStrategy(Searcher searcher, PointVectorStrategy strategy, Point myLocation) { var vs = strategy.MakeDistanceValueSource(myLocation); var q = new FunctionQuery(vs); // Returns a score for each document based on a ValueSource TopDocs hits = searcher.Search(q, null, 100); return(hits); }
public static TopDocs DistanceFilter_PointVectorStrategy(Searcher searcher, PointVectorStrategy strategy, Point myLocation) { var ctx = strategy.GetSpatialContext(); var q = new MatchAllDocsQuery(); var filter = strategy.MakeFilter(new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(myLocation, DistanceUtils.Dist2Degrees(2000, DistanceUtils .EARTH_MEAN_RADIUS_KM)))); TopDocs hits = searcher.Search(q, filter, 100); return(hits); }
public PointVectorDistanceFieldComparatorSource(Point center, PointVectorStrategy strategy) { if (center == null) { throw new ArgumentNullException("center"); } if (strategy == null) { throw new ArgumentNullException("strategy"); } _center = center; _strategy = strategy; }
//query builders public QueryHelper <TModel> SortByDistanceFromPoint(Expression <Func <TModel, object> > exp, double longitude, double latitude, bool desc = false) { if (sort == null) { sort = new Sort(); sorts = new List <SortField>(); } string key = getName(exp.Body.ToString()); var strat = new PointVectorStrategy(ctx, key); IPoint pt = ctx.MakePoint(longitude, longitude); ValueSource valueSource = strat.MakeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM); //the distance (in km) sort = new Sort(valueSource.GetSortField(desc)); //.Rewrite(indexSearcher);//false=asc dist return(this); }
private void IndexDocuments(IEnumerable <City> cities) { Analyzer analyzer = new StandardAnalyzer(Version); var indexWriter = new IndexWriter(_directory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED); _ctx = SpatialContext.GEO; _strategy = new PointVectorStrategy(_ctx, SpartialFieldName); foreach (var doc in CreateDocuments(cities, _strategy)) { indexWriter.AddDocument(doc); } indexWriter.Commit(); indexWriter.Dispose(); }
public void Document_Writing_To_Index_Spatial_Data_And_Search_On_100km_Radius_GetPointVectorStrategy() { SpatialContext ctx = SpatialContext.GEO; PointVectorStrategy strategy = new PointVectorStrategy(ctx, GeoLocationFieldName); // NOTE: This works without this custom query and only using the filter too // there's also almost zero documentation (even in java) on what MakeQueryDistanceScore actually does, // the source is here https://lucenenet.apache.org/docs/3.0.3/d0/d37/_point_vector_strategy_8cs_source.html#l00133 // And as it's noted it shouldn't be used: "this is basically old code that hasn't been verified well and should probably be removed" // It's also good to note that PointVectorStrategy is 'obsolete' as it exists now under the Legacy namespace in Java Lucene // NOTE: The SpatialExample uses MatchAllDocsQuery however the strategy can create a query too, the source is here: // https://lucenenet.apache.org/docs/3.0.3/d0/d37/_point_vector_strategy_8cs_source.html#l00104 // which looks like it verifies that the search is using an Intersects/Within query and then creates a // ConstantScoreQuery - which probably makes sense because a 'Score' for a geo coord doesn't make a lot of sense. RunTest(ctx, strategy, a => strategy.MakeQuery(a)); }
private static Filter CreateGeoDistanceFilter(GeoDistanceFilter geoDistanceFilter) { Filter result = null; if (geoDistanceFilter?.FieldName != null && geoDistanceFilter.Location != null) { var spatialContext = SpatialContext.GEO; var distance = DistanceUtils.Dist2Degrees(geoDistanceFilter.Distance, DistanceUtils.EARTH_MEAN_RADIUS_KM); var searchArea = spatialContext.MakeCircle(geoDistanceFilter.Location.Longitude, geoDistanceFilter.Location.Latitude, distance); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, searchArea); var fieldName = LuceneSearchHelper.ToLuceneFieldName(geoDistanceFilter.FieldName); var strategy = new PointVectorStrategy(spatialContext, fieldName); result = strategy.MakeFilter(spatialArgs); } return(result); }
private static List <IFieldable> AddPoint(double lng, double lat) { SpatialContext ctx = SpatialContext.GEO; var strategy = new PointVectorStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName);//var strategy = new PrefixTreeStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName); List <IFieldable> pointFields = new List <IFieldable>(); Point shape = ctx.MakePoint(lng, lat); foreach (var f in strategy.CreateIndexableFields(shape)) { if (f != null) { pointFields.Add(f); } } return(pointFields); }
private List <IFieldable> AddPoint(Item item) { List <IFieldable> pointFields = new List <IFieldable>(); var setting = spatialConfigurations.LocationSettings.Where(i => i.TemplateId.Equals(item.TemplateID)).FirstOrDefault(); if (setting == null) { return(pointFields); } SpatialContext ctx = SpatialContext.GEO; SpatialPrefixTree grid = new GeohashPrefixTree(ctx, 11); var strategy = new PointVectorStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName); double lng = 0; double lat = 0; bool parsedLat = false; bool parsedLong = false; if (!string.IsNullOrEmpty(item[setting.LatitudeField])) { parsedLat = Double.TryParse(item[setting.LatitudeField], out lat); } if (!string.IsNullOrEmpty(item[setting.LongitudeField])) { parsedLong = Double.TryParse(item[setting.LongitudeField], out lng); } if (!parsedLat && !parsedLong) { return(pointFields); } pointFields = AddPoint(lng, lat); return(pointFields); }
public IEnumerable <Param> ParamsProvider() { var ctorArgs = new List <Param>(); SpatialContext ctx = SpatialContext.GEO; SpatialPrefixTree grid; SpatialStrategy strategy; grid = new QuadPrefixTree(ctx, 25); strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad"); ctorArgs.Add(new Param(strategy)); grid = new GeohashPrefixTree(ctx, 12); strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash"); ctorArgs.Add(new Param(strategy)); strategy = new PointVectorStrategy(ctx, "pointvector"); ctorArgs.Add(new Param(strategy)); strategy = new BBoxStrategy(ctx, "bbox"); ctorArgs.Add(new Param(strategy)); return(ctorArgs); }
public DistanceCustomScoreQuery(Query subQuery, PointVectorStrategy strategy, Point origin) : base(subQuery) { _strategy = strategy; _origin = origin; }
protected virtual IList <IIndexableField> ConvertToProviderFields(IndexDocumentField field) { // TODO: Introduce and use metadata describing value type var result = new List <IIndexableField>(); var fieldName = LuceneSearchHelper.ToLuceneFieldName(field.Name); var store = field.IsRetrievable ? Field.Store.YES : Field.Store.NO; //var index = field.IsSearchable ? Field.Index.ANALYZED : field.IsFilterable ? Field.Index.NOT_ANALYZED : Field.Index.NO; if (field.Value is string) { foreach (var value in field.Values) { result.Add(new StringField(fieldName, (string)value, store)); if (field.IsSearchable) { result.Add(new StringField(LuceneSearchHelper.SearchableFieldName, (string)value, Field.Store.NO)); } } } else if (field.Value is bool) { var booleanFieldName = LuceneSearchHelper.GetBooleanFieldName(field.Name); foreach (var value in field.Values) { var stringValue = value.ToStringInvariant(); result.Add(new StringField(fieldName, stringValue, store)); result.Add(new StringField(booleanFieldName, stringValue, Field.Store.NO)); } } else if (field.Value is DateTime) { var dateTimeFieldName = LuceneSearchHelper.GetDateTimeFieldName(field.Name); foreach (var value in field.Values) { //TODO //var numericField = new NumericField(fieldName, store, index != Field.Index.NO); //numericField.SetLongValue(((DateTime)value).Ticks); //result.Add(numericField); result.Add(new StringField(dateTimeFieldName, value.ToStringInvariant(), Field.Store.NO)); } } else if (field.Value is GeoPoint) { var geoPoint = (GeoPoint)field.Value; result.Add(new StringField(fieldName, geoPoint.ToString(), Field.Store.YES)); var shape = _spatialContext.MakePoint(geoPoint.Longitude, geoPoint.Latitude); var strategy = new PointVectorStrategy(_spatialContext, fieldName); foreach (var f in strategy.CreateIndexableFields(shape)) { result.Add(f); } } else { double t; if (double.TryParse(field.Value.ToStringInvariant(), NumberStyles.Float, CultureInfo.InvariantCulture, out t)) { var facetableFieldName = LuceneSearchHelper.GetFacetableFieldName(field.Name); foreach (var value in field.Values) { var stringValue = value.ToStringInvariant(); //TODO //var numericField = new NumericField(fieldName, store, index != Field.Index.NO); //numericField.SetDoubleValue(double.Parse(stringValue, NumberStyles.Float, CultureInfo.InvariantCulture)); //result.Add(numericField); result.Add(new StringField(facetableFieldName, stringValue, Field.Store.NO)); } } else { result.AddRange(field.Values.Select(value => new StringField(fieldName, value.ToStringInvariant(), store))); } } return(result); }
public static TopDocs DistanceQueryAndSort_PointVectorStrategy(Searcher searcher, PointVectorStrategy strategy, Point myLocation) { var ctx = strategy.GetSpatialContext(); var q = strategy.MakeQuery(new SpatialArgs( SpatialOperation.IsWithin, ctx.MakeCircle(myLocation, DistanceUtils.Dist2Degrees(20000, DistanceUtils.EARTH_MEAN_RADIUS_KM)))); TopDocs hits = searcher.Search(q, null, 100, new Sort(new SortField("pointvector", new PointVectorDistanceFieldComparatorSource(myLocation, strategy)))); return(hits); }
public static void SearchSample() { Directory dir = new RAMDirectory(); Analyzer analyzer = new StandardAnalyzer(Version); var indexWriter = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.UNLIMITED); SpatialContext ctx = SpatialContext.GEO; var strategy = new PointVectorStrategy(ctx, SpartialFieldName); //var precision = 8; // Precision 8 means down to 19 meter - higher precision consumes more memory //SpatialPrefixTree grid = new GeohashPrefixTree(ctx, precision); //var strategy = new RecursivePrefixTreeStrategy(grid, spartialFieldName); var docs = CreateSearchDocuments(GetDeals(), strategy); foreach (var doc in docs) { indexWriter.AddDocument(doc); } indexWriter.Commit(); indexWriter.Dispose(); // "Current" position Point littleMermaid = ctx.MakePoint(12.599239, 55.692848); //var parser = new QueryParser(Version, "title", analyzer); //Query q = parser.Parse("deal"); Query q = new MatchAllDocsQuery(); // NOTE: MatchAllDocsQuery always returns score as 1.0 // Add distance from current point to the scoring q = new DistanceCustomScoreQuery(q, strategy, littleMermaid); //q = new RecursivePrefixTreeStrategyDistanceCustomScoreQuery(q, strategy, littleMermaid, spartialFieldName); // Remove everything more than 2000 km away var filter = strategy.MakeFilter(new SpatialArgs(SpatialOperation.Intersects, ctx.MakeCircle(littleMermaid, DistanceUtils.Dist2Degrees(2000, DistanceUtils.EARTH_MEAN_RADIUS_KM)))); // Ensures the most recent searcher is used without destroying the Lucene IndexReader cache (via NRT) var searcherManager = new SearcherManager(dir); var collector = new GroupTopDocsCollector(5, SupplierFieldName); var searcher = searcherManager.GetSearcher(); try { searcher.Search(q, filter, collector); } finally { searcherManager.ReleaseSearcher(searcher); } var hits = collector.GroupTopDocs(); Console.WriteLine("Found {0} document(s) that matched query '{1}':", hits.TotalHits, q); foreach (var match in hits.GroupScoreDocs) { Document doc = searcher.Doc(match.Doc); Console.WriteLine("Best match '{0}' in group '{1}' with count {2} (MaxDoc: Score {3} Location '{4}')", doc.Get(TitleFieldName), match.GroupFieldValue, match.GroupCount, match.Score, doc.Get(LocationNameFieldName)); } }
public PointVectorDistanceFieldComparator(Point origin, int numHits, PointVectorStrategy strategy) { _values = new DistanceValue[numHits]; _originPt = origin; _strategy = strategy; }
protected virtual IList <IIndexableField> ConvertToProviderFields(IndexDocumentField field) { var result = new List <IIndexableField>(); var fieldName = LuceneSearchHelper.ToLuceneFieldName(field.Name); var store = field.IsRetrievable ? Field.Store.YES : Field.Store.NO; switch (field.Value) { case string _: foreach (var value in field.Values) { result.Add(new StringField(fieldName, (string)value, store)); if (field.IsSearchable) { result.Add(new StringField(LuceneSearchHelper.SearchableFieldName, (string)value, Field.Store.NO)); } } break; case bool _: var booleanFieldName = LuceneSearchHelper.GetBooleanFieldName(field.Name); foreach (var value in field.Values) { var stringValue = value.ToStringInvariant(); result.Add(new StringField(fieldName, stringValue, store)); result.Add(new StringField(booleanFieldName, stringValue, Field.Store.NO)); } break; case DateTime _: var dateTimeFieldName = LuceneSearchHelper.GetDateTimeFieldName(field.Name); foreach (var value in field.Values) { var numericField = new Int64Field(fieldName, ((DateTime)value).Ticks, store); result.Add(numericField); result.Add(new StringField(dateTimeFieldName, value.ToStringInvariant(), Field.Store.NO)); } break; case GeoPoint _: var geoPoint = (GeoPoint)field.Value; result.Add(new StringField(fieldName, geoPoint.ToString(), Field.Store.YES)); var shape = _spatialContext.MakePoint(geoPoint.Longitude, geoPoint.Latitude); var strategy = new PointVectorStrategy(_spatialContext, fieldName); result.AddRange(strategy.CreateIndexableFields(shape)); break; default: if (double.TryParse(field.Value.ToStringInvariant(), NumberStyles.Float, CultureInfo.InvariantCulture, out _)) { var facetableFieldName = LuceneSearchHelper.GetFacetableFieldName(field.Name); foreach (var value in field.Values) { var stringValue = value.ToStringInvariant(); var doubleField = new DoubleField(fieldName, double.Parse(stringValue, NumberStyles.Float, CultureInfo.InvariantCulture), store); result.Add(doubleField); result.Add(new StringField(facetableFieldName, stringValue, Field.Store.NO)); } } else { result.AddRange(field.Values.Select(value => new StringField(fieldName, value.ToStringInvariant(), store))); } break; } return(result); }