Implementing Tagging and Excluding Filters with Solrj / Spring Data Solr - solr

I am trying to implement a Solr Facet search with multi-select on a field. To take this example: http://docs.lucidworks.com/display/solr/Faceting#Faceting-LocalParametersforFaceting, I would like to generate this call to solr:
q=mainquery&fq=status:public&fq={!tag=dt}doctype:pdf&facet=on&facet.field={!ex=dt}doctype
I am not sure how to call this using solrj (java) as I don't want to add a simple filed but I need to include the tagging and excluding (!tag=dt and !ex=dt). Any ideas what the java code should look like?
I am using Spring-Data-Solr which seems to be too basic to make such an advance call. So I think I need to go a level lower and use solrj. Either solution would be great (solrj or spring-data-solr)

The following block should create the querystring you want.
SimpleFacetQuery query = new SimpleFacetQuery(new SimpleStringCriteria("mainquery"))
.addFilterQuery(new SimpleQuery(new Criteria("status").is("public")))
.addFilterQuery(new SimpleQuery(new Criteria("{!tag=dt}doctype").is("pdf")));
query.setFacetOptions(new FacetOptions("{!ex=dt}doctype"));
solrTemplate.queryForFacetPage(query, YourBean.class);

With link I can do this :-
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("fq", "{!tag=dt}doctype:pdf");
params.add("facet.field", "{!ex=dt}doctype");

Using SolrQuery (which is a subclass of ModifiableSolrParams from the other answer):
solrQuery.addFilterQyery("{!tag=dt}doctype:pdf");
solrQuery.addFacetField("{!ex=dt}doctype");

Related

local param not working in solr 8 but working in solr 5

I am migrating from solr 5.5 to solr 8.
Query for solr 5.5 looks like -
qt=/dismax
product_fields_Ref1=product_concept^279841
sku_and_product_fields_Ref1=silhouette_concept^234256 $product_fields_Ref1
product_phrase_Ref2=pant
concept_with_synonyms_ref1=({!edismax2 qf=$sku_and_product_fields_Ref1 v=$product_phrase_Ref2})
top_concept_query_ref= (+({!maxscore v=$concept_with_synonyms_ref1}) )
productQueryRef3=+(+({!query v=$cq})) +( ({!maxscore v=$top_concept_query_ref}) )
sq=+{!lucene v=$productQueryRef3}
q={!parent tag=top which=$pq score=max v=$sq}
But is giving error on solr 8.0 with error -
Error from server at http://localhost:8080/products: org.apache.solr.search.SyntaxError: Query Field '$product_fields_Ref1' is not a valid field name
If I modify query like this (remove the variable product_fields_Ref1 and append the value directly in sku_and_product_fields_Ref1) -
qt=/dismax
sku_and_product_fields_Ref1=silhouette_concept^234256 product_concept^279841
product_phrase_Ref2=pant
concept_with_synonyms_ref1=({!edismax2 qf=$sku_and_product_fields_Ref1 v=$product_phrase_Ref2})
top_concept_query_ref= (+({!maxscore v=$concept_with_synonyms_ref1}) )
productQueryRef3=+(+({!query v=$cq})) +( ({!maxscore v=$top_concept_query_ref}) )
sq=+{!lucene v=$productQueryRef3}
q={!parent tag=top which=$pq score=max v=$sq}
Problem is I can not modify this query since the value of param "product_fields_Ref1" are being compiled from a large number of places.
I am using defType=dismax only.
Can any one guide what needs to be fixed?
I went through the source code of "org.apache.solr.search.ExtendedDismaxQParser"
and found out the is a new validation check added which DOES NOT allow local parameter in qf field edismax parser (this check has been introduced starting solr 8.0.0).
Check works like this -
any parameter coming in qf MUST match a field in schema (I am not using schema-less mode) of the core. method is
validateQueryFields(up);
This executes in
public Query parse() throws SyntaxError { ... }
of
org.apache.solr.search.ExtendedDismaxQParser
I got this working by creating my own custom parser and removed this validator after overriding the parse() method.
Support for Local Parameters has changed significantly in more recent versions of Solr (see https://lucene.apache.org/solr/guide/7_5/solr-upgrade-notes.html#solr-7-2)
The only way that I have been able to get some of the behavior back is by setting lucene as the default parser in solrconfig.xml and then passing the local parameters in the query, for example: q={!dismax qf=$param1}coffee
I understand that you can get back the old behavior by switching to LuceneMatchVersion 7.1.0 but that change did not work for me.

java code for solr geolocation indexing

I am using solr for fixing my indexing and searching feature and a beginner to solr.
I actually want to index the geolocation into solr index and also want to make queries on it so went through some articles,
http://wiki.apache.org/solr/SpatialSearch
And exactly some schema type are present in my schema.xml.
Now my question is I want to write a java code to index the geolocation while indexing it for dynamic geolocation fields. So how to write it and is there any sample java code for indexing it. I looked for it but didn't found any so please if anybody can help me with it.
I also understand that when indexing we would need to write some thing like :
document.addField(myDynLocFld+"_p", val));
If using this approach what should be val an instance of location object with both lat and lng value embedded in it. So how to counter this or is there any diferent approach in solr java for this?
Thanking in advance.
Check this sample of code,
// Store the index in memory:
//Directory directory = new RAMDirectory();
// To store an index on disk
Directory directory = FSDirectory.open("/tmp/testindex");
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);
IndexWriter iwriter = new IndexWriter(directory, config);
Document doc = new Document();
String text = "This is the text to be indexed.";
doc.add(new Field("fieldname", text, TextField.TYPE_STORED));
iwriter.addDocument(doc);
iwriter.close();
For more details check Lucene APIs.

Parsing Solr Results - javabin format

I am trying to integrate solr with java using solrj. The result retrieved are of the format
{
numFound=3,
start=0,
docs=[
SolrDocument{
id=IW-02,
name=iPod&iPodMiniUSB2.0Cable,
manu=Belkin,
manu_id_s=belkin,
cat=[
electronics,
connector
],
features=[
carpoweradapterforiPod,
white
],
weight=2.0,
price=11.5,
price_c=11.50,
USD,
popularity=1,
inStock=false,
store=37.7752,
-122.4232,
manufacturedate_dt=TueFeb1418: 55: 59EST2006,
_version_=1452625905160552448
}
Now this is the javabin format. How do I extract results from this? Have heard that solrj does convert the results to objects by itself. But cant figure out how.
Thanks for the help in advance.
Let solrReply be the response object. The you can access different parts of the result using appropriate params. Say you want docs, you can do:
docs = solrReply['docs']
if you want the first result you could do:
first = solrReply['docs'][0]
Within a result you can access each field in the same way.

Indexing PDF documents with addtional search fields using SolrNet?

I found this article useful when indexing documents, however, how can I attach additional fields so I can pass in, say, the ID of the document in our database for use in displaying the search results? I thought by using the Fields (Of the ExtractParameters class) property I could index additional data with the document, but that doesn't seem to work or that is not its function.
Example code:
var solr = ObjectLocator.Instance.Resolve<ISolrOperations<IndexDocument>>();
var guid = Guid.NewGuid().ToString();
using (var fileStream = System.IO.File.OpenRead(Server.MapPath("~/files/") + "greenroof.pdf"))
{
var response =
solr.Extract(
new ExtractParameters(fileStream, "greenRoof1234")
{
ExtractFormat = ExtractFormat.Text,
ExtractOnly = false,
Fields = new[] { new ExtractField("field1", "value1"), new ExtractField("field2", "value2") }
});
}
#aitchnyu is correct, passing the values via the literal.field=value method is the correct way to do this.
However, according to this post on ExtractingRequestHandler support in the SolrNet Google Group, there was a bug with the ExtractParameters.Fields not working properly. This was fixed in the 0.4.0.X versions of SolrNet. Please make sure you are using one of the latest versions of SolrNet. You can obtain that by one of the following means:
Project Site Downloads
NuGet PreRelease Package
Also that discussion has some good examples of using the ExtractingRequestHandler in SolrNet as well as a workaround for adding the additional field values if you cannot upgrade to a newer version of SolrNet.
This is sufficient: http://wiki.apache.org/solr/ExtractingRequestHandler#Literals .
In general use a literal.field=value while uploading.
It turned out not to be an issue with SOLRNet, but my knowledge of SOLR, in general. I needed to specify the fields in my schema. After i added the fields to my schema they were visible in my SOLR query.

How to use the composite filter of app-engine data store queries?

I have the this function:
#Override
public List<Expense> getExpensesBetween(Date firstDate, Date secondDate) {
Query query = new Query(expenseEntityKind);
query.addFilter("date", Query.FilterOperator.GREATER_THAN_OR_EQUAL, secondDate);
query.addFilter("date", Query.FilterOperator.GREATER_THAN_OR_EQUAL, firstDate);
Iterable<Entity> entities = service.prepare(query).asIterable();
return getReturnedExpenses(entities);
}
I want to return all the expenses between two date i.e greater than or equal 2012-05-01 AND less than or equal 2012-06-01. I took a look at the documentations of Google app-engine. It says that we must use Composite Filters. Google documentations: " However, if you want to set more than one filter on a query, you must use CompositeFilter. You must have at least two filters to use CompositeFilter. However, this documentations seems to be old and i didn't find any function called setFilter();. Any suggestion how to create a composite filter ? I use App-engine sdk 1.6.6. Thanks in advance.
The following is taken from https://cloud.google.com/appengine/docs/java/datastore/queries which might be helpful here
Filter heightMinFilter =
new FilterPredicate("height",
FilterOperator.GREATER_THAN_OR_EQUAL,
minHeight);
Filter heightMaxFilter =
new FilterPredicate("height",
FilterOperator.LESS_THAN_OR_EQUAL,
maxHeight);
//Use CompositeFilter to combine multiple filters
Filter heightRangeFilter =
CompositeFilterOperator.and(heightMinFilter, heightMaxFilter);
The documentation you are looking is for the newest version (1.7.0). That features have been just introduced. Here an example of how to use CompositeFilter (1.7.0 also).

Resources