How to re-rank documents based on their attributes rather than just their field relevance? - apache

I'm trying to use Solr to re-rank document results based relevance to the user searching. For example, if I search joann*this could return documents where the Name field is anything from joanna to joanne. What I'm trying to do is to return documents that match on certain attributes that I have as well-- this could be something like us both having the field Location = "NYC".
So my question is two fold- is there a way to grab and handle a users information when they are making a query and also is there a way to re-rank based on these additional field values? Would this look more like writing some code or just an expanded query?

it looks to me like you are talking about functionality that Query Reranking exactly provides. Did you check that out?

Related

Few questions about Grails' createCriteria

I read about createCriteria, and kind of interested on how these works, and its usability in providing values for dropdown box.
So say, i have a table in the database, Resource table, where i have defined the table in the domain class called Resource.groovy. Resource table has a total of 10 columns, where 5 of it are
Material Id
Material description
Resource
Resource Id
Product Code
So using the createCriteria, and i can use just like a query to return the items that i want to
def resList = Resource.createCriteria().list {
and {
eq('resource', resourceInstance)
ne('materialId', '-')
}
}
Where in the above, i want to get the data that matches the resource = resourceInstance, and none of the materialId is equal to '-'.
I want to use the returned data from createCriteria above on my form, where i want to use some of the column on my select dropdown. Below is the code i used for my select dropdown.
<g:select id="resourceId" name="resourceId"
from="${resList}"
disabled="${actionName != 'show' ? false : true}" />
How do i make it so that in a dropdown, it only shows the values taken from column Product Code? I believe the list created using createCriteria returns all 10 columns based on the createCriteria's specification. But i only want to use the Product Column values on my dropdown.
How do i customize the data if in one of the select dropdown in my form, i wanted to show the values as "Resource Id - Resource Description"? The values are combination of more than 1 columns for one select dropdown but i don't know how to combine both in a single select dropdown.
I read that hql and GORM query are better ways of fetching data from table than using createCriteria. Is this true?
Thanks
First of all refer to the document for using select in Grails. To answer all questions:
Yes, the list to select from in the dropdown can be customized. In this case it should be something like from="${resList*.productCode}"
Yes, this can be customized as well with something like
from="${resList.collect { \"${it.resourceId} - ${it.resourceDesc}\" } }"
It depends. If there are associations involved in a domain then using Criteria will lead to eager fetches which might not be required. But with HQL one gets the flexibility of tailoring the query as needed. With latest version of Grails those boundries are minimized a lot. Usage of DetachedCriteria, where queries etc are recommended whereever possible. So it is kind of mixing and matching to the scenario under consideration.

PrefixQuery on multiple fields and based on another field's value?

I am working on an auto complete solution with lucene. Do I need to call the PrefixQuery each time for each field I want to search on? Also, what if I only want to search a small set of items based off another filed's ID?
For example: Let's say I have a list of users that I have indexed. Those users belong to a specific project. I only want to PrefixQuery search users that are on, say, projectId 1.
Assuming your schema has fields "projectid" and "name", you would query for documents (users) matching the query:
+projectid:1 +name:prefix*
where 1 is the projectid and "prefix" is the name prefix you want to search for.

Solr: Search in multiple fields BUT STOP if documents match was found

I want to search in multiple fields in Solr.
(In know the concept of the copy-fields and I know the (e)dismax search handler.)
So I have an orderd list of fields, I want the terms to be searched against.
1.) SKU
2.) Name
3.) Description
4.) Summary
and so on.
Now, when the query matches a term, let's say in the SKU field, I want this match and no further searches in the proceeding fields.
Only, if there are NO matches at all in the first field (SKU field), the second field (in this case "name") should be used and so on.
Is this possible with Solr?
Do I have to implement my own Lucene Search Handler for this?
Any advice is welcome!
Thank you,
Bernhard
I think your case requires executing 4 different searches. If you implement you very own SearchHandler you could avoid penalty of search result accumulation in 4 different request. Which means, you would send one query, and custom SearchHandler would execute 4 searches and prepare one result set.
If my guess is right you want to rank the results based on the order of the fields. If so then you can just use standard query like
q=sku:(query)^4 OR name:(query)^3 OR description:(query)^2 OR summary:(query)
this will rank the results by the order of the fields.
Hope is helps.

Apache SOLR search by category

I am using apache-solr-1.4.1 and jdk1.6.0_14.
I have the following scenario.
I have 3 categories of data indexed in SOLR i.e. CITIES, STATES, COUNTRIES.
When I query data from SOLR I need the search result from SOLR based on the following criteria:
In a single query to SOLR I need data fetched from SOLR grouped by each category with a predefined results count for each category.
How can I specify this condition in SOLR?
I have tried to use SOLR Field Collapsing feature, but I am not able to get the desired output from SOLR.
Please suggest.
My solution is not exactly what you have asked but is my take on what SOLR does best, which is full text search. Instead of grouping the results by "category", I'd suggest you order the results by relevance score but also provide a facet count for the category values. In my experience users expect a "search" to behave like Google, with the best matches at the top. Deviating form this norm confuses the user in most cases.
If you want exactly as you have asked (actual results grouped by category) then you could use a relational database and do a group_by or write a custom function query with SOLR (I cannot advise on this as I've never done it).
More info: index the data with the appropriate fields, e.g. name, population, etc. But also add a field called "category", which would have a value of either CITIES, STATES or COUNTRIES. Then perform a standard SOLR search, which will return results in order of relevance - i.e. best matches at the top. As part of the request, you can specify a facet.field=category, which will return counts for the search results for each of the given categories (in the "facet" results section). In the UI you can then create links for each category facet which performs the original search plus &fq=category:CITIES, etc., thus restricting results to just that category. See the facetting overview on the SOLR wiki for more info.

How to design a database table structure for storing and retrieving search statistics?

I'm developing a website with a custom search function and I want to collect statistics on what the users search for.
It is not a full text search of the website content, but rather a search for companies with search modes like:
by company name
by area code
by provided services
...
How to design the database for storing statistics about the searches?
What information is most relevant and how should I query for them?
Well, it's dependent on how the different search modes work, but generally I would say that a table with 3 columns would work:
SearchType SearchValue Count
Whenever someone does a search, say they search for "Company Name: Initech", first query to see if there are any rows in the table with SearchType = "Company Name" (or whatever enum/id value you've given this search type) and SearchValue = "Initech". If there is already a row for this, UPDATE the row by incrementing the Count column. If there is not already a row for this search, insert a new one with a Count of 1.
By doing this, you'll have a fair amount of flexibility for querying it later. You can figure out what the most popular searches for each type are:
... ORDER BY Count DESC WHERE SearchType = 'Some Search Type'
You can figure out the most popular search types:
... GROUP BY SearchType ORDER BY SUM(Count) DESC
Etc.
This is a pretty general question but here's what I would do:
Option 1
If you want to strictly separate all three search types, then create a table for each. For company name, you could simply store the CompanyID (assuming your website is maintaining a list of companies) and a search count. For area code, store the area code and a search count. If the area code doesn't exist, insert it. Provided services is most dependent on your setup. The most general way would be to store key words and a search count, again inserting if not already there.
Optionally, you could store search date information as well. As an example, you'd have a table with Provided Services Keyword and a unique ID. You'd have another table with an FK to that ID and a SearchDate. That way you could make sense of the data over time while minimizing storage.
Option 2
Treat all searches the same. One table with a Keyword column and a count column, incorporating SearchDate if needed.
You may want to check this:
http://www.microsoft.com/sqlserver/2005/en/us/express-starter-schemas.aspx