How to perform exact search using solr QueryManager in a XWIki Extension?

Hello,

I have a piece of code to perform some custom solr search in one of my API implemented in an XWiki extension

		Query slrQuery = this.queryManager.createQuery(String.format("*%s*", driveId), "solr");
			
	        List<String> filterQuery = new ArrayList<String>();
	        // We want only visible documents with a CollabClass
	        filterQuery.add("{!tag=type}type:(\"DOCUMENT\")");
	        filterQuery.add("class:Collaboratory.Apps.Drive.Code.DriveClass");
	        filterQuery.add("hidden:false");
	        //filterQuery.add("defType=dismax");
	        
	        List<String> qf = new ArrayList<String>();
	        qf.add(DriveSearchResult.fieldMap.get("DriveRepositoryId"));

	        slrQuery.bindValue("qf", qf);
	        
            QueryResponse response = null;
            SolrDocumentList documents = null;

            response = (QueryResponse) slrQuery.execute().get(0);
            documents = response.getResults();

I read that I should use a KeywordTokenizer to perform exact match in solr

https://solr.apache.org/guide/6_6/tokenizers.html

But how can I configure that in XWiki with embedded solr ? Or is it possible to perform the exact search just on this query ? I don’t wan’t it apply to the default XWiki solr search.

No, because the way Solr matches the query against the specified fields (DriveRepositoryId) depends on how those fields are indexed, so it depends on the Solr schema. You need to see in which ways the `DriveRepositoryId`` is indexed (the same information can be indexed in multiple ways to support multiple types of queries) and whether one of those index fields supports exact matching. Otherwise you need to write code that adds the missing index field for exact matching, but this is more complex.

Have you tried suffixing the property name with _string when setting the query fields (e.g. DriveRepositoryId_string)?

Hey thanks for answering :slight_smile: sorry to respond just now I was on other issues.

I’ve been trying with the `_string" suffix but it doesn’t change anything actually it’s even not finding anything ^^. I think it’s a very standart string field from a string input in a class created with App Within Minutes.

But I’m looking also for exact search on very common XWiki string such as document Title. For exemple if I search for “few words” in my search by title function ( title are title of XWikiDocument ). it will return all document containings “few” or “words” in the title but it’s often too much result dependings of the search.

I can’t believe there is no easy way to perform exact search on solr using the java lib just for some requests it sounds very basics :frowning:

So maybe I should simplify my question and not made it depedent of my AWM I will take a general exemple which works for any wiki pages

Every XWikiDocument have title and name

Imagine I have 5 XWikiDocument with title

few things
few example
another words
few words
something else

And i have a solr query

		Query slrQuery = this.queryManager.createQuery("*few words*", "solr");
			
	        List<String> filterQuery = new ArrayList<String>();
	        filterQuery.add("{!tag=type}type:(\"DOCUMENT\")");
	        filterQuery.add("hidden:false");
	        //filterQuery.add("defType=dismax");
	        
	        List<String> qf = new ArrayList<String>();
	        qf.add("title_");

	        slrQuery.bindValue("qf", qf);
	        
            QueryResponse response = null;
            SolrDocumentList documents = null;

            response = (QueryResponse) slrQuery.execute().get(0);
            documents = response.getResults();

Ok so in that exemple I’m searching for few words in the title of all the XWikiDocument.

But it will return all theses results

`few things`
`few example`
`another words`
`few words`

Me I want an exact search which return

`few words`

And so far I didn’t found anything to perform something as simple as that :frowning:

I just eard about theses tokenizer Tokenizers | Apache Solr Reference Guide 6.6

But it seems to be apply to every Solr request and even like that I don’t know how to use it in java from the xwiki query builder.

The page title is currently indexed only as TextField and not as StrField, so it doesn’t support exact matching. See Field Types Included with Solr | Apache Solr Reference Guide 8.5 . For exact matching there’s no need to use Solr. You can write a simple database query. See https://extensions.xwiki.org/xwiki/bin/view/Extension/Query+Module .

{{velocity}}
$services.query.xwql('where doc.title = :title').bindValue('title', 'Sandbox Test Page 1').addFilter('hidden').addFilter('unique').execute()

$services.query.xwql('where doc.title like :title').bindValue('title').anyChars().literal('Test Page').anyChars().query().addFilter('hidden').addFilter('unique').execute()
{{/velocity}}

Some object properties are indexed both as TextField and StrField, which means they support both free text search and exact matching. This is the case for instance with “String” and “Static List” properties. So if you create an xclass with a property of type “String” and then add objects of this type to existing pages you will be able to query with Solr those pages on that property using exact match. This is the case with the page tags for instance, which are stored as a Static List property, so you can write a query like this:

property.XWiki.TagClass.tags:"two words"

and you can add a search facet on tags (using exact match) as indicated on https://extensions.xwiki.org/xwiki/bin/view/Extension/Solr+Search+Application#HFacetingonObjectProperties .

I solved this few month ago, forgot to update the status

At the end the answer I was looking was so easy …

Query slrQuery = this.queryManager.createQuery("\"few words\"~100, "solr");
			

https://www.solrtutorial.com/solr-query-syntax.html

1 Like