JAVA Lucene not giving search results on Field? - java

I am creating a Lucene Document like this:
Document document = new Document();
document.add(new Field(FIELD_FOLDER_PATH,mSearchInput, Field.Store.YES, Field.Index.NOT_ANALYZED ));
Reader reader = new FileReader(file);
document.add(new Field(FIELD_CONTENTS, reader));
indexWriter.addDocument(document);
When executing Query on CONTENTS and also using wild character * I am able to fetch results:
QueryParser queryParser = new QueryParser (Version.LUCENE_36,FIELD_CONTENTS, analyzer);
Query query = queryParser.parse(searchString+"*");
But when I am using the same Query for FIELD_FOLDER_PATH , I am getting no results:
QueryParser queryParser = new QueryParser (Version.LUCENE_36,FIELD_FOLDER_PATH, analyzer);
Query query = queryParser.parse(FolderPath+"*");
However only when I am providing the exact string , I am able to fetch the results.
My Question is : Why I am not able to use (*) to fetch results in FIELD_FOLDER_PATH? Is it because of the way I am creating the field?

You should use wildcard query to support this kind of feature.
This link would help :
http://lucene.apache.org/core/old_versioned_docs/versions/3_0_1/api/core/org/apache/lucene/search/WildcardQuery.html
So what you should do exactly is create two queries one using queryparser and other using wildcard query , then use both the queries in a BooleanQuery with "SHOULD" clause for both the queries.
for details on boolean Query visit this link :
http://lucene.apache.org/core/old_versioned_docs/versions/3_0_2/api/core/org/apache/lucene/search/BooleanQuery.html

Related

how to parse search string without fields limit in lucene

For example:
title:lucene+((author:jack)^300.0 (bookname:how to use lucene)^200.0 (price:[100 TO 200])^100.0)~1
Is there anyWay parse the lucene query string to Query Object like Query query = Function(String queryString) in lucene?
You can use the classic QueryParser to build a parser:
QueryParser parser = new QueryParser(default_field_name, analyzer);
If you provide field names in your query string (as you do in your example), then the default field name is not used.
The analyzer should typically be the same as the analyzer which was used to build the index. For example, the StandardAnalyzer:
Analyzer analyzer = new StandardAnalyzer();
And then you can use the string containing your query as follows:
Query query = parser.parse(your_query_string);
The demo code provided as part of Lucene shows an example of this approach. See lines 118 and 135 in the SearchFiles.html code.

Lucene : getting same length results when querying

So I've tried absolutely all query types in lucene and none of them seemed to work. What I'm trying to do is simple: I want to query the index but I wanna get exact same matches. And when I say exact same I mean the results should have the same text (obviously) AND the same length, something that usually happens when querying a database. So for example when I'm searching for jodie foster, I'm getting this text as one of the results : List of awards and nominations received by Jodie Foster. I don't want results containing the search term, I want results that are exactly like the search term.
First of all, this is how I'm building the lucene index:
IndexWriterConfig luceneConfig = new IndexWriterConfig(new StandardAnalyzer());
Path path = Paths.get("C:/Users/i_l_g/Desktop/DBpedia/qls_labels");
Directory dir = FSDirectory.open(path);
IndexWriter writer = new IndexWriter(dir, luceneConfig);
while (rs.next()) {
Document doc = new Document();
doc.add(new Field("entity", rs.getString("entity"), TextField.TYPE_STORED));
doc.add(new Field("label", rs.getString("label"), TextField.TYPE_STORED));
writer.addDocument(doc);
}
rs is a ResultSet type variable and I'm obviously just extracting data from a table and indexing them using Lucene.
Next, I tried querying this index using all types of queries, but I'm getting the same set of results every time, it's almost as if I didn't even change the query type. My last attempt was using a PhraseQuery:
StandardAnalyzer analyzer = new StandardAnalyzer();
PhraseQuery.Builder builder = new PhraseQuery.Builder();
PhraseQuery q;
builder.add(new Term("label","jodie"));
builder.add(new Term("label","foster"));
builder.setSlop(0);
q=builder.build();
This is the set of results I'm getting every single time, if it could be of any help:
Found 5 hits.
1. Jodie Foster
2. Alicia Christian "Jodie" Foster
3. Jodie Foster filmography
4. Impress Jodie Foster
5. List of awards and nominations received by Jodie Foster
I didn't really think that it would take me that much time, I've been trying to solve this issue for 2 days now and I've visited tens of links and there appears to be no one that has ever had this problem. Please help.

Match-no-documents Query object in Lucene

How do I create a new Query instance having the property of not matching any document, analogous to the MatchAllDocsQuery, but opposite?
A Boolean query without any clause returns no documents.
Query blank = new BooleanQuery();
For newer versions of Lucene you can use the Builder with the same result.
Query blank = new BooleanQuery.Builder().build();

Java/Lucene Search multiple fields for a substring

I'm Using Lucence V3.1 & Java 1.6.
I'm trying to write code (using java and lucene) that allows me to do multi-field phrase search. However, i don't want the phrase to exactly match the value in the field. What i want is to check if the phrase is actually a substring of the value in the field. I tried the following but no luck yet:
IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);
BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("<field-name>", "<text>"));
booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
Hits hits = searcher.Search(booleanQuery);
Just use quotes? Like "this is the substring". This surely works with the lucene QueryParser
If to be used in a Query use a PhraseQuery. See also http://lucene.apache.org/core/old_versioned_docs/versions/3_1_0/api/core/org/apache/lucene/search/PhraseQuery.html
which analyzer u used while indexing??
if u used Standard Analyzer, you should not face a problem like this...
PS: always use same analyzer for both indexing and searching

Lucene: queries and docs with multiple fields

I have a collection of documents consisting of several fields, and I need to perform queries with several terms coming from multiple fields.
What do you suggest me to use ? MultiFieldQueryParser or MultiPhraseQuery ?
thanks
How about BooleanQuery?
http://lucene.apache.org/java/3_0_2/api/core/org/apache/lucene/search/BooleanQuery.html
Choice of Analyzer
First of all, watch out which analyzer you are using. I was stumped for a while only to realise that the StandardAnalyzer filters out common words like 'the' and 'a'. This is a problem when your field has the value 'A'. You might want to consider the KeywordAnalyzer:
See this post around the analyzer.
// Create an analyzer:
// NOTE: We want the keyword analyzer so that it doesn't strip or alter any terms:
// In our example, the Standard Analyzer removes the term 'A' because it is a common English word.
// https://stackoverflow.com/a/9071806/231860
KeywordAnalyzer analyzer = new KeywordAnalyzer();
Query Parser
Next, you can either create your query using the QueryParser:
See this post around overriding the default operator.
// Create a query parser without a default field in this example (the first argument):
QueryParser queryParser = new QueryParser("", analyzer);
// Optionally, set the default operator to be AND (we leave it the default OR):
// https://stackoverflow.com/a/9084178/231860
// queryParser.setDefaultOperator(QueryParser.Operator.AND);
// Parse the query:
Query multiTermQuery = queryParser.parse("field_name1:\"field value 1\" AND field_name2:\"field value 2\"");
Query API
Or you can achieve the same by constructing the query yourself using their API:
See this tutorial around creating the BooleanQuery.
BooleanQuery multiTermQuery = new BooleanQuery();
multiTermQuery.add(new TermQuery(new Term("field_name1", "field value 1")), BooleanClause.Occur.MUST);
multiTermQuery.add(new TermQuery(new Term("field_name2", "field value 2")), BooleanClause.Occur.MUST);
Delete the Documents that Match the Query
Then we finally pass the query to the writer to delete documents that match the query:
See my answer here, related to this answer.
See the answer to this question.
// Remove the document by using a multi key query:
// http://www.avajava.com/tutorials/lessons/how-do-i-combine-queries-with-a-boolean-query.html
writer.deleteDocuments(multiTermQuery);

Categories