Port of Solr's FunctionQuery (v1.4) Returns a score for each document based on a ValueSource, often some function of the value of a field. Note: This API is experimental and may change in non backward-compatible ways in the future
Inheritance: Lucene.Net.Search.Query
        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");
        }
        public void CreateSpatialFilterAndWeight(PointRadiusCriterion geoFilter, Filter currentFilter, Weight currentWeight)
        {
            var spatialContext = SpatialContext.GEO;
            var geohashTree = new GeohashPrefixTree(spatialContext, 10);
            var strategy = new RecursivePrefixTreeStrategy(geohashTree, geoFilter.FieldName);
            var point = spatialContext.MakePoint(geoFilter.Longitude, geoFilter.Latitude);

            var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, spatialContext.MakeCircle(point,
                DistanceUtils.Dist2Degrees(geoFilter.RadiusKm, DistanceUtils.EARTH_MEAN_RADIUS_KM)));

            var circle = spatialContext.MakeCircle(point,
                    DistanceUtils.Dist2Degrees(geoFilter.RadiusKm, DistanceUtils.EARTH_MEAN_RADIUS_KM));
            var circleCells = strategy.GetGrid().GetWorldNode().GetSubCells(circle);

            var luceneFilters = new List<Filter>();
            if (currentFilter != null)
                luceneFilters.Add(currentFilter);

            var tempSpatial = strategy.MakeFilter(spatialArgs);
                luceneFilters.Add(tempSpatial);
            
            if (geoFilter.Sort != PointRadiusCriterion.SortOption.None)
            {
                var valueSource = strategy.MakeDistanceValueSource(point);
                var funcQ = new FunctionQuery(valueSource);
                // this is a bit odd... but boosting the score negatively orders results 
                if (geoFilter.Sort == PointRadiusCriterion.SortOption.Ascending)
                {
                    funcQ.Boost = -1;
                }
                spatialWeight = funcQ.CreateWeight(this);
                spatialWeight.GetSumOfSquaredWeights();

                luceneFilters.Add(new QueryWrapperFilter(currentWeight.Query));
            }

            spatialFilter = new ChainedFilter(luceneFilters.ToArray(), 1);
        }
Example #3
0
        public Query MakeQueryWithValueSource(SpatialArgs args, ValueSource valueSource)
        {
            var bq = new BooleanQuery();
            var spatial = MakeFilter(args);
            bq.Add(new ConstantScoreQuery(spatial), Occur.MUST);

            // This part does the scoring
            Query spatialRankingQuery = new FunctionQuery(valueSource);
            bq.Add(spatialRankingQuery, Occur.MUST);
            return bq;
        }
Example #4
0
        /* scores[] are in docId order */

        protected void checkValueSource(ValueSource vs, float[] scores, float delta)
        {
            FunctionQuery q = new FunctionQuery(vs);

            //    //TODO is there any point to this check?
            //    int expectedDocs[] = new int[scores.length];//fill with ascending 0....length-1
            //    for (int i = 0; i < expectedDocs.length; i++) {
            //      expectedDocs[i] = i;
            //    }
            //    CheckHits.checkHits(random(), q, "", indexSearcher, expectedDocs);

            TopDocs docs = indexSearcher.Search(q, 1000); //calculates the score
            for (int i = 0; i < docs.ScoreDocs.Length; i++)
            {
                ScoreDoc gotSD = docs.ScoreDocs[i];
                float expectedScore = scores[gotSD.Doc];
                assertEquals("Not equal for doc " + gotSD.Doc, expectedScore, gotSD.Score, delta);
            }

            CheckHits.checkExplanations(q, "", indexSearcher);
        }
		public override Query MakeQuery(SpatialArgs args)
		{
			// For starters, just limit the bbox
			var shape = args.GetShape();
			if (!(shape is Rectangle || shape is Circle))
				throw new InvalidShapeException("Only Rectangles and Circles are currently supported, found ["
					+ shape.GetType().Name + "]");//TODO

			Rectangle bbox = shape.GetBoundingBox();
			if (bbox.GetCrossesDateLine())
			{
				throw new InvalidOperationException("Crossing dateline not yet supported");
			}

			ValueSource valueSource = null;

			Query spatial = null;
			SpatialOperation op = args.Operation;

			if (SpatialOperation.Is(op,
				SpatialOperation.BBoxWithin,
				SpatialOperation.BBoxIntersects))
			{
				spatial = MakeWithin(bbox);
			}
			else if (SpatialOperation.Is(op,
			  SpatialOperation.Intersects,
			  SpatialOperation.IsWithin))
			{
				spatial = MakeWithin(bbox);
				var circle = args.GetShape() as Circle;
				if (circle != null)
				{
					// Make the ValueSource
					valueSource = MakeValueSource(args);

					var vsf = new ValueSourceFilter(
						new QueryWrapperFilter(spatial), valueSource, 0, circle.GetRadius());

					spatial = new FilteredQuery(new MatchAllDocsQuery(), vsf);
				}
			}
			else if (op == SpatialOperation.IsDisjointTo)
			{
				spatial = MakeDisjoint(bbox);
			}

			if (spatial == null)
			{
				throw new UnsupportedSpatialOperation(args.Operation);
			}

			if (valueSource != null)
			{
				valueSource = new CachingDoubleValueSource(valueSource);
			}
			else
			{
				valueSource = MakeValueSource(args);
			}
			Query spatialRankingQuery = new FunctionQuery(valueSource);
			var bq = new BooleanQuery();
			bq.Add(spatial, Occur.MUST);
			bq.Add(spatialRankingQuery, Occur.MUST);
			return bq;

		}
Example #6
0
			public FunctionWeight(Searcher searcher, FunctionQuery q)
			{
				enclosingInstance = q;
				this.searcher = searcher;
				//q.func.CreateWeight(searcher);
			}
Example #7
0
 public FunctionWeight(Searcher searcher, FunctionQuery q)
 {
     enclosingInstance = q;
     this.searcher     = searcher;
     //q.func.CreateWeight(searcher);
 }