Lucene Search 2 fields - lucene

I tried to search the best matching product (bounty paper towel) from a certain retailer, my query is the following, but the query returns 0 hit.
BooleanQuery.Builder combine = new BooleanQuery.Builder();
Query q1 = new QueryParser("product", new StandardAnalyzer()).parse(QueryParser.escape("product:" + "bounty paper towel"));
combine.add(q1, BooleanClause.Occur.SHOULD); // find best name match
Query q2 = new QueryParser("retailer", new StandardAnalyzer()).parse(QueryParser.escape("retailer:" + "Target"));
combine.add(q2, BooleanClause.Occur.MUST); // Must from this retailer
searcher.search(combine.build(), hitsPerPage).scoreDocs;
Is there anything wrong with the way I build the query?

You are escaping things you don't want to escape. You pass the string "product:bounty paper towel" to the escape method, which will escape the colon, which you don't want to escape. In effect, that query, after escaping and analysis, will look like this:
product:product\:bounty product:paper product:towels
You should escape the search terms, not the entire query. Something like:
parser.parse("product:" + QueryParse.escape("bounty paper towels"));
Also, it looks like you are looking for a phrase query there, in which case, it should be surrounded by quotes:
parser.parse("product:\"" + QueryParse.escape("bounty paper towels") + "\"");
The way your building your boolean query looks fine. You could leverage the query parser syntax to accomplish the same thing, if you prefer, like this:
parser.parse(
"product:\"" + QueryParse.escape("bounty paper towels") + "\""
+ "+retailer:" + QueryParse.escape("Target")
);
But again, there is nothing wrong with BooleanQuery.Builder instead.

Used Lucene too many years ago, but let me try...
Rewrite you parse part as follow:
...
Query q1 = new QueryParser("product", new StandardAnalyzer())
.parse("bounty paper towel");
...
Query q2 = new QueryParser("retailer", new StandardAnalyzer())
.parse("Target"));
...
So your query should contain only target information, but not a column name - since it is already referenced before.

Related

Lucene -Lexical error while parsing Proximity query

I write a code for dynamic search on a database while using lucene.net.
I started creating queries and find the position of the results, It worked great!!
but when I used Proximity Searches, I get an error:
Lexical error at line 1, column 72. Encountered: after : "\" "
my Searching function:
private static List<String> GeneralSearch(string txt, Table type)
{
txt= "10~" + txt;
string newQuery = "";
foreach (var field in fields[type])
{
newQuery += field + ": " + txt + " OR ";
}
newQuery = newQuery.Substring(0, newQuery.Length - 4)+" ";
parser.MultiTermRewriteMethod =
MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
BooleanQuery bq = new BooleanQuery();
Query query = parser.Parse(newQuery);
bq.Add(query, Occur.MUST);
bq.Add(new TermQuery(new Term("tbl", type.ToString())), Occur.MUST);
TopDocs hits = searcher.Search(bq, reader.MaxDoc);........
The "txt" variable contained a query like that:
txt= "I like to read"
The function create a new query for searching on all the field of specific table
title: 10~"I like to read" OR content: 10~"I like to read"
I think my problem is maybe that the language alignment was right to left.
If you have an idea, it will help me !!
I can't speak to the specific error, however your query is malformed in two ways
The slop (proximity) operator must trail a query not lead the query
Literal phrase queries must be enclosed with double quotes
It's wise to log the result of a query parse with Query.ToString(). Assuming StandardAnalyzer, your query is parsing to something like this:
(text:10~0.5 text:i text:like text:read) +tbl:somevalue
What you think is your slop is parsed as a term query with the default slop value of 0.5
text:10~0.5
and what you thought was a phrase query is in reality parsing to multiple term queries because your phrase is not double quoted:
text:i text:like text:read
You want your raw query to look something like this:
text: "I like to read"~10
Here's a nice guide regarding Lucene query syntax. Good luck!

Cannot run simply query, getting "missing right parenthesis" error

What is wrong with this query?
select author_num from (henry_author where (contains(author_first,'Albert') > 0))
Keeps giving me an error that is is missing a right parenthesis?
SELECT author_num FROM henry_author WHERE author_first LIKE '%Albert%';
or, probably better to account for data inconsistencies:
SELECT author_num FROM henry_author WHERE UPPER(author_first) LIKE '%ALBERT%';
The % is a wildcard matching zero or more characters. So %ALBERT% means anything can be before or after 'ALBERT', which is effectively what your contains() function is doing.
UPPER is just a function which converts the string into upper case characters, which makes it easier to deal with potential data inconsistencies, ie. someone typed in 'albert' instead of 'Albert', etc.
Since you're using JDBC, you might want to structure your query to use PreparedStatement which will allow you to parameterize your query like so:
final String sqlSelectAuthorNum = "SELECT author_num FROM henry_author WHERE UPPER(author_first) LIKE ?";
final PreparedStatement psSelectAuthorNum = conn.prepareStatement(sqlSelectAuthorNum);
// now execute your query someplace in your code.
psSelectAuthorNum.setString(1, "%" + authorName + "%");
final ResultSet rsAuthorNum = psSelectAuthorNum.executeQuery();
if (rsAuthorNum.isBeforeFirst()) {
while (rsAuthorNum.next()) {
int authorNumber = rsAuthorNum.getInt(1);
// etc...
}
}

Hibernate return empty result if using LIKE condition with univarchar columns (Sybase)

Let's suppose I have a table: Person(Name: univarchar) and this table contains a row "abc".
I search Person by using Hibernate (Criteria API and HQL):
Criteria API:
Criteria c = session.createCriteria(Person.class);
c.add(Restrictions.ilike(name,"abc"));
return c.list();
HQL:
String query = "from Person where lower(name) like :name";
Query q = session.createQuery(query);
query.setString("name","abc");
return query.list();
It return empty result. However, when I use Interactive SQL of Sybase to execute SQL statement that is generated by Hibernate, it return a row "abc".
I found a solution for HQL case. This is to use rtrim function:
String query = "from Person where lower(rtrim(name)) like :name";
...
But my problem is I want to use Criteria API and I cannot find any ways to trim name column by using Criteria API.
Thanks and sorry for my poor English.
Have you tried with this code :
Criteria c = session.createCriteria(Person.class);
c.add(Restrictions.ilike(name,"abc",MatchMode.ANYWHERE));
return c.list();
If this will not work then Read this. Its similar Just he wants to trim while Order you want to trim while Restrictions.

How to create if and or parameter statement in Crystal Reports

Apologies for posting a new question but I just can't think how to search for this question.
I'm creating a Crystal Report with multiple parameters and at the moment each one is connected by an ‘AND’ in the Report > Selection Formulas part of the report (not the SQL command part).
I haven’t fully authored the report and it contains lots of arrays to deal with multiple text values and wildcard searches but I think my question should be more around logic than the technical functions.
So…
Parameters are for things like product code, date range, country, batch number etc.
Currently the parameters I’m concerned with are Faults and keyword searches for complaints against products.
(Query 1) If all other parameters are set to default I can enter Fault Combination = ‘Assembly – Code’ and that gives me 17 records.
(Query 2) Entering keyword = ‘%unit%’ gives me 55 records.
The 2 parameters are connected by an AND so if I use Fault Combination = ‘Assembly – Code’ and Keyword = ‘%unit%’ then I get 12 records. If the connect the 2 queries with OR then I get 12 records.
If I compare the unique records, in excel, between query 1 & 2 then there are 60 records with Fault Combination = ‘Assembly – Code’ OR keyword = ‘%unit%.
How can write the parameter formula to get the 60 unique records with one query?
Many thanks!
Gareth
Edit - Code Added
This is the segment i'm concerned with. The arrays are defined earlier in the statement and the '*' & '%' parts of the query below are just to deal with the different wildcard operators between SQL and Crystal. There are a lot of other parameters but these 3 are the only ones that need the OR kind or connection.
Hope that helps!
(IF "%" LIKE array_fn2
THEN ((ISNULL({Command.FaultNoun})=TRUE) OR ({Command.FaultNoun} LIKE '*'))
ELSE IF {Command.RecordType} = 'Complaint'
THEN ({Command.FaultNoun} like array_fn2)
ELSE ((ISNULL({Command.FaultNoun})=TRUE) OR ({Command.FaultNoun} LIKE '*'))) AND
(IF "%" LIKE array_fa2
THEN ((ISNULL({Command.FaultAdjective})=TRUE) OR ({Command.FaultAdjective} LIKE '*'))
ELSE IF {Command.RecordType} = 'Complaint'
THEN ({Command.FaultAdjective} like array_fa2)
ELSE ((ISNULL({Command.FaultAdjective})=TRUE) OR ({Command.FaultAdjective} LIKE '*'))) AND
(IF ("%" LIKE array_k2) OR ({Command.RecordType} = 'Sale')
THEN ((ISNULL({Command.ActualStatements})=TRUE) OR ({Command.ActualStatements} LIKE '*')
OR (ISNULL({Command.ResultsAnalysis})=TRUE) OR ({Command.ResultsAnalysis} LIKE '*')
OR (ISNULL({Command.Observation})= TRUE) OR ({Command.Observation} LIKE '*'))
ELSE
({Command.ActualStatements} like array_k2) OR
({Command.ResultsAnalysis} like array_k2) OR
({Command.Observation} like array_k2))

Using contains in Linq query produces error

I have a pretty straight forward query that is producing this error at runtime: Only arguments that can be evaluated on the client are supported for the String.Contains method.
The query is supposed to find only the categories that have transfers assigned to them. The transfers can be listed in several categories so there is no table relationship. The Categoryidhash contains data like "7~34~25~42~47". I just realized while writing this that searching for '7' will return multiple results, "7" & '47' Etc. Thats ok i'll just change id's to all double digits. meanwhile...
How can I fix this?
Private Function GetCategoryList() As List(Of Category)
Dim lst As List(Of Category) = New List(Of Category)
Using db As New IPCDataDataContext
lst = (From c In db.Categories
From t In db.Transfers
Where t.CategoryIDhash.Contains(c.ID.ToString)
Select c).ToList()
Return lst
End Using
End Function
The exception means that Contains only accepts arguments that can be converted to fixed variable in SQL. So something like Where t.CategoryIDhash.Contains(someVariable.ToString) would be possible, because someVariable.ToString can be evaluated client-side.
I don't really understand this restriction, because in SQL it is perfectly possible to use a LIKE clause with a string that is built in the SQL statement itself. This is demonstrated by the statement that fixes your problem:
lst = (From c In db.Categories
From t In db.Transfers
Where SqlMethods.Like(t.CategoryIDhash, "%" + c.ID.ToString "%")
Select c).ToList()
This generates (and executes) SQL like
...
WHERE [t1].[CategoryIDhash] LIKE (#p0 + (CONVERT(NVarChar,[t0].[ID]))) + #p1
(where #p0 and #p1 are the % characters.
Although you could do this, I wonder if you're on the right track by using this CategoryIDhash. I think you should convert it to a FK relationship (if it's in your hands to modify the database).