Solrnet equivalent for frange in a facet query for Distance - solr

I have implemented Spatial Search and need to generate facets for ranges or 'buckets' of distance in Solr: the following link helped me here - http://wiki.apache.org/solr/SpatialSearch#How_to_facet_by_distance
I found the solution to the following question
Faceting on distance in solr- how to generate links that search withing a given range of distance helpful.
I am using Solrnet to generate Solr queries from my .NET based site. I cant find a link that would help me to generate a frange part (italicized) of the query as below. Please help in pointing me to the code to generate this using solrnet.
&q=:&sfield=store&pt=45.15,-93.85**&facet.query={!frange l=0 u=5}geodist()&facet.query={!frange l=5.001 u=3000}geodist()**.

I am assuming that you are already using ExtraParams to set the sField & pt parameters. You should be able to add the facet.query parameters to this as well.
var results = solr.Query(SolrQuery.All, new QueryOptions
{
ExtraParams = new Dictionary<string, string> {
{ "sfield", "store" } ,
{ "pt", "45.15,-93.85" }
{ "facet.query", "{!frange l=0 u=5}geodist()" } ,
{ "facet.query", "{!frange l=5.001 u=3000}geodist()" } ,
}
});
return results;
Additionally, you might be able to use SolrFacetQuery combined with LocalParams to build the facet queries. Check the following links for some examples:
https://code.google.com/p/solrnet/wiki/Facets
How to add Spatial Solr to a Solrnet query
Update:
As stated in the comments, the use of the ExtraParams does not work because it is a dictionary object and as a result does not allow for multiple facet.query parameters. However, I was able to use the Facet Queries as described in the SolrNet Facet Wiki page linked above to create the following:
var facet1 = new SolrFacetQuery(new SolrQuery("{!frange l=0 u=5}geodist()}"));
var facet2 = new SolrFacetQuery(new SolrQuery("{!frange l=5.001 u=3000}geodist()}"));
var results = solr.Query(SolrQuery.All, new QueryOptions
{
ExtraParams = new Dictionary<string, string>
{
{"sfield", "store"},
{"pt", "45.15,-93.85"}
},
Facet = new FacetParameters
{
Queries = new[]
{
facet1, facet2
}
}
});
return results;

Related

DotNet Core Azure Search SDK - filtering results

We are trying to implement Filter functionality into Azure (Cognitive) Search. I was hoping to find some nice SDK methods that hide all the ugly parts, but so far the only example I found looks like this (source):
SearchParameters parameters = new SearchParameters()
{
Filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", groups.Select(g => g.ToString()))),
Select = new[] { "application essays" }
};
I was wondering, whether I am missing some docs. Or maybe it is on the roadmap?
Check out our new Azure.Search.Documents SDK we released last month. It does have OData filter helps as you can find here:
int stars = 4;
SearchOptions options = new SearchOptions
{
// Filter to only Rating greater than or equal our preference
Filter = SearchFilter.Create($"Rating ge {stars}"),
Size = 5, // Take only 5 results
OrderBy = { "Rating desc" } // Sort by Rating from high to low
};
It'll escape string parameters correctly. The OData $filter syntax still requires raw input, but the type helpers in the formattable string should make your situation easier: you don't have to worry about escaping values yourself.

Using variables in azure search filter

I am creating a search for a website and using many filter options. I want to use filter on my many search results and for that i saw Filter property in SearchParameters for Azure Cognitive search.
What i want is to pass a variable in Filter when i try to pass those parameters in filter search.
Is there any possible way that i do not have to manually pass the Boulevard House from my data and use the variable houseName instead as i have provided options to choose and this is just plain-hardcode.
Any refernce will help as well, as i tried to read the documents but in vain.
{
Filter = String.Format("HouseName eq '{0}'", houseName)
} ;
var names = new List<Search>();
if (nameResult.Results.Count > 0)
{
foreach (SearchResult<Search> results in nameResult.Results)
{
names.Add(results.Document);
}
}
NameSearchViewModel nameSearchViewModel = new NameSearchViewModel();
nameSearchViewModel.Grants = names;
return View(namesSearchViewModel);
I'm assuming you are using the C# SDK. You could do something like this
parameters = new SearchParameters
{
Filter = String.Format("HouseName eq '{0}'", houseName)
}

SolrNET localParams (for tagging filterQuery) cause exception with multiple values

I am trying to implement localParams in a SolrNET implementation but running into problems when we try to prefix a field with the localParams in a query with multiple values.
We are trying to use localParams for tagging and excluding filters. See: http://wiki.apache.org/solr/SimpleFacetParameters#Tagging_and_excluding_Filters for more information.
To achieve this we need to tag the filterQuery for our filter/facet field (referred to as field_name below) and exclude the tag in our facetField. The facetField exclusion of a tag works perfectly but we are having problems with the filterQuery when multiple values are selected.
I have found the difference in the generated query string to be the following:
Without localParams:
fq=field_name:"value1,value2"
With localParams:
fq=({!paramKey=paramValue}field_name:"value1" OR {!paramKey=paramValue}field_name:"value2")
Expected:
fq={!paramKey=paramValue}field_name:"value1,value2"
We are initiating the Solr query with a call to: SolrInstance.Query(ISolrQuery query, QueryOptions options) and the filter query affected by this issue can be found in the QueryOptions.FilterQueries collection as defined below:
SolrNet.SolrQueryInList
.FieldName: {!paramKey=paramValue}field_name
.List
.string[]
"value1",
"value2"
The localParam(s) has/have been prefixed with the .FieldName property. This doesn't work, presumably because Solr doesn't recognise {!paramKey=paramValue}field_name as a valid FieldName and this seems to be why the exception is thrown.
Can anyone provide any advise on how to implement localParams for SolrNET without getting this issue. The implementation works fine for single values but throws the exception below for multiple values:
[SolrNet.Exceptions.InvalidFieldException] = {"Bad Request"}
We are using the following versions:
SolrNET: v0.3.0
Solr: v4.3.0
The code for applying the localParams to our filterQueries can be found below:
foreach (var filterQuery in parameters.FilterQuery)
{
if (parameters.LocalParams.Any(x => x.Field == filterQuery.Field && x.QueryType == QueryType.Filter))
{
var valueDictionary = parameters.LocalParams.Where(x => x.QueryType == QueryType.Filter && x.Field == filterQuery.Field).ToDictionary(param => param.Action, param => param.Value);
filterQuery.Field = new SolrQuery(new LocalParams(valueDictionary) + filterQuery.Field).Query;
}
}
The above code iterates over filterQueries and prefixes the .Field with the localParams syntax.

SolrNet Faceting question

Using SolrNet for querying & faceting. I have a combination of int, tdate and string fields I would like to facet on. However I am unable to mix SolrFacetFieldQuery and SolrFacetQuery (for ranges) and SolrFacetDateQuery (for date ranges) in the same query. I get an error "no best type found for implicitly typed array". How should this best be handled? Clearly don't want to send multiple queries for getting the other facets.
I know this is something silly, but been vexing me....
results = solr.Query(qry
, new QueryOptions
{
Rows = 250,
Facet = new FacetParameters
{
Queries = new[]
{
new SolrFacetFieldQuery("Registry"),
new SolrFacetFieldQuery("Status"),
new SolrFacetFieldQuery("Type"),
//this is where it throws up "no best type found for implicty typed array"
new SolrFacetQuery(lessThan25),
}
}
});
C# can't infer the common base type, so you have to be explicit about it when creating the array:
Queries = new ISolrFacetQuery[] {
new SolrFacetFieldQuery("Registry"),
new SolrFacetFieldQuery("Status"),
new SolrFacetFieldQuery("Type"),
new SolrFacetQuery(lessThan25),
}

Solr and facet search

Does facet searching come built in when you setup your schema or do you have to do some things to set this up?
Does it basically work out of the box on all the fields that you have setup to be sortable?
then you just use the fq query syntax and it will return the facet xml along with the search results?
Is there a nice article on this that helped you first time around?
Yes, you can facet any indexed field out of the box. However it might not give you the results you expect until you configure faceting fields according to your data types.
Faceting is enabled and used through the facet.* parameters, not fq. fq is used when the user selects a facet value.
Some good Solr tutorials:
http://lucene.apache.org/solr/tutorial.html
http://www.lucidimagination.com/Community/Hear-from-the-Experts/Podcasts-and-Videos/Solr-Tutorial
Yes, Simply add &facet=true&facet.field={fieldname} to your request Url.
Here is another tutorial:Faceting
The below code in C#, by using SolrNet package.
The Facet you can do it on the fields stored in SOLR, make sure its string and doesn't have space for better results. The mincount is for limiting the minimum number to get listed in facet.
QueryOptions options = new QueryOptions
{
Facet = new FacetParameters
{
Queries = new ISolrFacetQuery[]
{
new SolrFacetFieldQuery("field1"),
new SolrFacetFieldQuery("field2")
},
MinCount = 20
}
};
And the below code to get the results, query - is the search entered in front end.
var result = solr.Query(query, options);
Faceting from Apache solr reference guide.
SolrNet package from Nuget Packages in C# provides a simple way of achieving this. The documentation helps. Here's an example,
public async Task SolrFaceting()
{
Console.WriteLine("facets");
var facetQuery = await _solr.QueryAsync(SolrQuery.All, new QueryOptions
{
Rows = 0,
Facet = new FacetParameters
{
Queries = new[]
{
new SolrFacetFieldQuery("FieldName1"),
new SolrFacetFieldQuery("FieldName2"),
new SolrFacetFieldQuery("FieldName3"),
new SolrFacetFieldQuery("FieldName4"),
},
Limit = 10
}
});
foreach (var facet in facetQuery.FacetFields["FieldName1"]) {
Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}
foreach (var facet in facetQuery.FacetFields["FieldName2"]) {
Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}
foreach (var facet in facetQuery.FacetFields["FieldName3"]) {
Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}
foreach (var facet in facetQuery.FacetFields["FieldName4"]) {
Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}
}

Resources