{"id":44590,"date":"2015-09-27T22:08:28","date_gmt":"2015-09-27T19:08:28","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=44590"},"modified":"2023-12-06T15:42:41","modified_gmt":"2023-12-06T13:42:41","slug":"advanced-lucene-query-examples","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html","title":{"rendered":"Advanced Lucene Query Examples"},"content":{"rendered":"<p><em>This article is part of our Academy Course titled <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/apache-lucene-fundamentals\/\">Apache Lucene Fundamentals<\/a>.<\/p>\n<p>In this course, you will get an introduction to Lucene. You will see why a library like this is important and then learn how searching works in Lucene. Moreover, you will learn how to integrate Lucene Search into your own applications in order to provide robust searching capabilities. Check it out <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/apache-lucene-fundamentals\/\">here<\/a>!<\/em><\/p>\n<div class=\"toc\">\n<h4>Table Of Contents<\/h4>\n<dl>\n<dt><a href=\"#intro\">1.Introduction<\/a><\/dt>\n<dt><a href=\"#lucenequery\">2.Lucene Queries<\/a><\/dt>\n<dt><a href=\"#luceneqryapi\">3.Lucene Query API<\/a><\/dt>\n<dt><a href=\"#basicsearch\">4.Basic search<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#terms\">4.1.Terms<\/a><\/dt>\n<dt><a href=\"#wildcardqry\">4.2.WildcardQuery<\/a><\/dt>\n<dt><a href=\"#boolop\">4.3.Boolean Operators<\/a><\/dt>\n<dt><a href=\"#grouping\">4.3.Grouping<\/a><\/dt>\n<dt><a href=\"#phrasequery\">4.4.PhraseQuery<\/a><\/dt>\n<dt><a href=\"#rangequery\">4.5.RangeQuery<\/a><\/dt>\n<dt><a href=\"#prefixquery\">4.6.Prefix Query<\/a><\/dt>\n<dt><a href=\"#fuzzyquery\">4.7.Fuzzy Query<\/a><\/dt>\n<\/dl>\n<\/dd>\n<\/dl>\n<\/div>\n<h2><a name=\"intro\"><\/a>1.Introduction<\/h2>\n<p>In a previous chapter we have learned the <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/lucene-components-overview\/\">different components of the Lucene search engine<\/a>. We also have built up a small search application using lucene indexing &amp; searching procedures. In this chapter we will talk about the Lucene queries.<\/p>\n<h2><a name=\"lucenequery\"><\/a>2.Lucene Queries<\/h2>\n<p>Lucene has a custom query syntax for querying its indexes. A query is broken up into terms and operators. Terms are of two types: <strong>1.Single Terms<\/strong> and <strong>2.Phrases<\/strong>. A Single Term is a single word such as &#8220;test&#8221; or &#8220;sample&#8221;. A Phrase is a group of words surrounded by double quotes such as &#8220;welcome lucene&#8221;. Multiple terms can be combined together with Boolean operators to form a more complex query. With Lucene Java, TermQuery is the most primitive Query. Then there\u2019s BooleanQuery, PhraseQuery, and many other Query subclasses to choose from.<\/p>\n<p><strong>Fields<\/strong> When performing a search we can specify the field you want to search in. Any existing field name can be used as field name. The syntax is, <em>FieldName:VALUE<\/em>. There are a few special field types that have their own syntax for defining the query term. For example DateTime: ModificationDate:&gt;&#8217;2010-09-01 12:00:00&#8242; We will explain searching operations on these fields in a later section.<\/p>\n<h2><a name=\"luceneqryapi\"><\/a>3.Lucene Query API<\/h2>\n<p>When a human-readable query is parsed by Lucene&#8217;s <code>QueryParser<\/code>, it is converted to a single concrete subclass of the Query class. We need some understanding of the underlying concrete Query subclasses. The relevant subclasses, their purpose, and some example expressions for each are listed in the following table:<\/p>\n<table>\n<tbody>\n<tr>\n<th><strong>Query Implementation<\/strong><\/th>\n<th><strong>Purpose<\/strong><\/th>\n<th><strong>Sample expressions<\/strong><\/th>\n<\/tr>\n<tr>\n<td><code>TermQuery<\/code><\/td>\n<td>Single term query, which effectively is a single word.<\/td>\n<td>reynolds<\/td>\n<\/tr>\n<tr>\n<td><code>PhraseQuery<\/code><\/td>\n<td>A match of several terms in order, or in near vicinity to one another.<\/td>\n<td>&#8220;light up ahead&#8221;<\/td>\n<\/tr>\n<tr>\n<td><code>RangeQuery<\/code><\/td>\n<td>Matches documents with terms between beginning and ending terms, including or excluding the end points.<\/td>\n<td>[A TO Z]<\/p>\n<p>{A TO Z}<\/td>\n<\/tr>\n<tr>\n<td><code>WildcardQuery<\/code><\/td>\n<td>Lightweight, regular-expression-like term-matching syntax.<\/td>\n<td>j*v?<\/p>\n<p>f??bar<\/td>\n<\/tr>\n<tr>\n<td><code>PrefixQuery<\/code><\/td>\n<td>Matches all terms that begin with a specified string.<\/td>\n<td>cheese*<\/td>\n<\/tr>\n<tr>\n<td><code>FuzzyQuery<\/code><\/td>\n<td>Levenshtein algorithm for closeness matching.<\/td>\n<td>tree~<\/td>\n<\/tr>\n<tr>\n<td><code>BooleanQuery<\/code><\/td>\n<td>Aggregates other Query instances into complex expressions allowing AND, OR, and NOT logic.<\/td>\n<td>reynolds AND &#8220;light up ahead&#8221;<\/p>\n<p>cheese* -cheesewhiz<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<br \/>\nAll of these <code>Query<\/code> implementations are in the <code>org.apache.lucene.search<\/code> package. The <code>BooleanQuery<\/code> is a bit of a special case because it is a <code>Query<\/code> container that aggregates other queries (including nested <code>BooleanQuery<\/code>s for sophisticated expressions).<\/p>\n<p>Here is a <code>BooleanQuery<\/code> based on the query snippet. Here we can see how the QueryParser-created query is equivalent to the API-created one:<\/p>\n<pre class=\"brush:java\">\npublic class RulezTest extends TestCase { \n  public void testJavaNotDotNet() throws Exception { \n    BooleanQuery apiQuery = new BooleanQuery(); \n    apiQuery.add(new TermQuery(new Term(\"contents\", \"java\")), true, false); \n    apiQuery.add(new TermQuery(new Term(\"contents\", \"net\")), true, false); \n    apiQuery.add(new TermQuery(new Term(\"contents\", \"dot\")), false, true); \n    Query qpQuery = QueryParser.parse(\"java AND net NOT dot\", \"contents\", new StandardAnalyzer()); \n    \/\/ Query and subclasses behave as expected with .equals \n    assertEquals(qpQuery, apiQuery); \n  } \n}\n<\/pre>\n<p>Some interesting features of the <code>Query<\/code> classes are their <code>toString<\/code> methods. Each <code>Query<\/code> subclass generates the equivalent (though not necessarily textually exact) <code>QueryParserexpression<\/code>. There are two variants: one is the standard <code>Object.toString<\/code> overridden method, and the other accepts the default field name. The following test case demonstrates how these two methods work, and illustrates how an equivalent (yet not the exact) expression is returned.<\/p>\n<pre class=\"brush:java\">\npublic void testToString() throws Exception { \n  Query query = QueryParser.parse(\"java AND net NOT dot\", \"contents\", new StandardAnalyzer()); \n  assertEquals(\"+java +net -dot\", query.toString(\"contents\")); \n  assertEquals(\"+contents:java +contents:net -contents:dot\", query.toString()); \n}\n<\/pre>\n<p>Notice that the expression parsed was &#8216;java AND net NOT dot&#8217;, but the expression returned from the <code>toString<\/code> methods used the abbreviated syntax &#8216;+java +net -dot&#8217;. Our first test case (<code>testJavaNotDotNet<\/code>) demonstrated that the underlying query objects themselves are equivalent.<\/p>\n<p>The no-arg <code>toString<\/code> method makes no assumptions about the field names for each term, and specifies them explicitly using field-selector syntax. Using these <code>toString<\/code> methods is handy for diagnosing <code>QueryParser<\/code> issues.<\/p>\n<h2><a name=\"basicsearch\"><\/a>4.Basic search<\/h2>\n<p>In most cases you want to look for a single term or a phrase, which is a group of words surrounded by double quotes (&#8220;sample application&#8221;). In these cases we will look for contents that has these words in their default index data that contains all the relevant text of the content.<\/p>\n<p>In more complex situations we may need some filtering based on the type or place of the content we are looking for, or we want to search in a specific field. Here we can learn how to construct more complex queries that can be used to effectively find content in a huge repository.<\/p>\n<h3><a name=\"terms\"><\/a>4.1.Terms<\/h3>\n<p>Suppose we want to search with a keyword &#8216;blog&#8217; in the tag field. The syntax will be,<\/p>\n<pre class=\"brush:bash\">tag :  blog<\/pre>\n<p>Now we will search with a phrase &#8216;lucene blog&#8217; in the tag field. For that the syntax will be,<\/p>\n<pre class=\"brush:bash\">tag :   \"lucene blog\"<\/pre>\n<p>Now lets search &#8216;lucene blog&#8217; in the tag field, and &#8216;technical blog&#8217; in the body,<\/p>\n<pre class=\"brush:bash\">tag : \"lucene blog\" AND body : \"technical blog\"<\/pre>\n<p>Suppose we want to search for phrase &#8216;lucene blog&#8217; in the tag field, and &#8216;technical blog&#8217; in the body or &#8216;searching blog&#8217; phrase in tag field,<\/p>\n<pre class=\"brush:bash\">(tag : \"lucene blog\" AND body : \"technical blog\") OR tag : \"searching blog\"<\/pre>\n<p>If we want to search &#8216;blog&#8217; not &#8216;lucene&#8217; in the tag field, the syntax will look alike,<\/p>\n<pre class=\"brush:bash\">tag : blog -tag : lucene<\/pre>\n<h3><a name=\"wildcardqry\"><\/a>4.2.WildcardQuery<\/h3>\n<p>Lucene supports single and multiple character wildcard searches within single terms (not within phrase queries).<\/p>\n<ol>\n<li>To perform a single character wildcard search use the &#8220;?&#8221; symbol.<\/li>\n<li>To perform a multiple character wildcard search use the &#8220;*&#8221; symbol.<\/li>\n<\/ol>\n<p>The single character wildcard search looks for terms that match that with the single character replaced. For example, to search for &#8220;text&#8221; or &#8220;test&#8221; we can use the search: te?t<\/p>\n<p>Multiple character wildcard searches looks for 0 or more characters. For example, to search for test, tests or tester, we can use the search:<\/p>\n<pre class=\"brush:bash\">test*<\/pre>\n<p>We can also use the wildcard searches in the middle of a term.<\/p>\n<pre class=\"brush:bash\">te*t<\/pre>\n<p>Here is an example of lucene wildcard search,<\/p>\n<p>Suppose, we have two files in the &#8216;files&#8217; directory.<\/p>\n<ol>\n<li>test-foods.txt\n<p>Here are some foods that Deron likes:<\/p>\n<p><code>hamburger<\/code><br \/>\n<code>french fries<\/code><br \/>\n<code>steak<\/code><br \/>\n<code>mushrooms<\/code><br \/>\n<code>artichokes<\/code>\n<\/li>\n<li>sample-food.txt\n<p>Here are some foods that Nicole likes:<\/p>\n<p><code>apples<\/code><br \/>\n<code>bananas<\/code><br \/>\n<code>salad<\/code><br \/>\n<code>mushrooms<\/code><br \/>\n<code>cheese<\/code><\/li>\n<\/ol>\n<p>Now we&#8217;ll look at the <code>LuceneWildcardQueryDemo<\/code> class. This class creates an index via the <code>createIndex()<\/code> method based on the text files mentioned above, and after this, it attempts to perform 8 wildcard searches against this index. Four of the searches are performed using the <code>WildcardQuery<\/code> class, and the other four searches are performed using the <code>QueryParser<\/code> class.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>The above 2 files are indexed first using a <code>createIndex()<\/code> method.<\/p>\n<pre class=\"brush:java\">\npublic static void createIndex() throws CorruptIndexException, LockObtainFailedException, IOException {\n  Analyzer analyzer = new StandardAnalyzer();\n  boolean recreateIndexIfExists = true;\n  IndexWriter indexWriter = new IndexWriter(INDEX_DIRECTORY, analyzer, recreateIndexIfExists);\n  File dir = new File(FILES_TO_INDEX_DIRECTORY);\n  File[] files = dir.listFiles();\n  for (File file : files) {\n    Document document = new Document();\n    String path = file.getCanonicalPath();\n    document.add(new Field(FIELD_PATH, path, Field.Store.YES, Field.Index.UN_TOKENIZED));\n    Reader reader = new FileReader(file);\n    document.add(new Field(FIELD_CONTENTS, reader));\n    indexWriter.addDocument(document);\n  }\n  indexWriter.optimize();\n  indexWriter.close();\n}\n<\/pre>\n<p>For doing the searching operations using the query parser, we can add a method named <code>searchIndexWithQueryParser()<\/code>,<\/p>\n<pre class=\"brush:java\">\npublic static void searchIndexWithQueryParser(String whichField, String searchString) throws IOException,ParseException {\n  System.out.println(\"\\\\nSearching for '\" + searchString + \"' using QueryParser\");\n  Directory directory = FSDirectory.getDirectory(INDEX_DIRECTORY);\n  IndexSearcher indexSearcher = new IndexSearcher(directory);\n  QueryParser queryParser = new QueryParser(whichField, new StandardAnalyzer());\n  Query query = queryParser.parse(searchString);\n  System.out.println(\"Type of query: \" + query.getClass().getSimpleName());\n  Hits hits = indexSearcher.search(query);\n  displayHits(hits);\n}\n<\/pre>\n<p>The <code>WildcardQuery<\/code> queries are performed in the <code>searchIndexWithWildcardQuery()<\/code> method, using the following code:<\/p>\n<pre class=\"brush:java\">\n  Directory directory = FSDirectory.getDirectory(INDEX_DIRECTORY); \n  IndexSearcher indexSearcher = new IndexSearcher(directory); \n  Term term = new Term(whichField, searchString); \n  Query query = new WildcardQuery(term); \n  Hits hits = indexSearcher.search(query);\n<\/pre>\n<p>The <code>QueryParser<\/code> queries are performed in the <code>searchIndexWithQueryParser()<\/code> method via:<\/p>\n<pre class=\"brush:java\">\n  Directory directory = FSDirectory.getDirectory(INDEX_DIRECTORY); \n  IndexSearcher indexSearcher = new IndexSearcher(directory); \n  QueryParser queryParser = new QueryParser(whichField, new StandardAnalyzer()); \n  Query query = queryParser.parse(searchString); \n  Hits hits = indexSearcher.search(query);\n<\/pre>\n<p>The <code>LuceneWildcardQueryDemo<\/code> class performs eight wildcard searches, as we can see from its main() method:<\/p>\n<pre class=\"brush:java\">\n  searchIndexWithWildcardQuery(FIELD_CONTENTS, \"t*t\"); \n  searchIndexWithQueryParser(FIELD_CONTENTS, \"t*t\"); \n  searchIndexWithWildcardQuery(FIELD_CONTENTS, \"sam*\"); \n  searchIndexWithQueryParser(FIELD_CONTENTS, \"sam*\"); \n  searchIndexWithWildcardQuery(FIELD_CONTENTS, \"te?t\"); \n  searchIndexWithQueryParser(FIELD_CONTENTS, \"te?t\"); \n  searchIndexWithWildcardQuery(FIELD_CONTENTS, \"*est\"); \n  try { \n    searchIndexWithQueryParser(FIELD_CONTENTS, \"*est\"); \n  } catch (ParseException pe) { \n    pe.printStackTrace(); \n  }\n<\/pre>\n<p>Lastly we will print the number of hits for each searching operations using a method like,<\/p>\n<pre class=\"brush:java\">\npublic static void displayHits(Hits hits) throws CorruptIndexException, IOException {\n  System.out.println(\"Number of hits: \" + hits.length());\n  Iterator&lt;Hit&gt; it = hits.iterator();\n  while (it.hasNext()) {\n    Hit hit = it.next();\n    Document document = hit.getDocument();\n    String path = document.get(FIELD_PATH);\n    System.out.println(\"Hit: \" + path);\n  }\n}\n<\/pre>\n<p>If we run the above code, it will show us,<\/p>\n<pre class=\"brush:bash\">Searching for 't*t' using WildcardQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/test-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for 't*t' using QueryParser\nType of query: WildcardQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/test-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for 'sam*' using WildcardQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/sample-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for 'sam*' using QueryParser\nType of query: PrefixQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/sample-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for 'te?t' using WildcardQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/test-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for 'te?t' using QueryParser\nType of query: WildcardQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/test-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for '*est' using WildcardQuery\nNumber of hits: 1\nHit: \/home\/debarshi\/workspace\/Test\/filesToIndex\/test-foods.txt<\/pre>\n<pre class=\"brush:bash\">Searching for '*est' using QueryParser\n\n  org.apache.lucene.queryParser.ParseException: Cannot parse '*est': '*' or '?' not allowed as first character in WildcardQuery \n  at org.apache.lucene.queryParser.QueryParser.parse(QueryParser.java:175) \n  at LuceneWildcardQueryDemo.searchIndexWithQueryParser(LuceneWildcardQueryDemo.java:81) \n  at LuceneWildcardQueryDemo.main(LuceneWildcardQueryDemo.java:46)\n<\/pre>\n<ol>\n<li>The first query uses a <code>WildcardQuery<\/code> object with &#8220;t*t&#8221;. Since &#8220;t*t&#8221; matches &#8220;test&#8221; in the index, this query returns 1 hit.<\/li>\n<li>The second query uses a <code>QueryParser<\/code> to query &#8220;t*t&#8221;. The QueryParser <code>parse()<\/code> method returns a <code>WildcardQuery<\/code>, and the query returns 1 hit, since it&#8217;s basically identical to the first query.<\/li>\n<li>The third query uses a <code>WildcardQuery<\/code> object with &#8220;sam*&#8221;. This wildcard query gets one hit, since &#8220;sam*&#8221; matches &#8220;sample&#8221;.<\/li>\n<li>The fourth query uses <code>QueryParser<\/code> with &#8220;sam*&#8221;. Notice, however, that QueryParser&#8217;s <code>parse()<\/code> method returns a <code>PrefixQuery<\/code> rather than a <code>WildcardQuery<\/code>. Since the asterisk is at the end of &#8220;sam*&#8221;. This PrefixQuery<\/code> for &#8220;sam*&#8221; gets a hit, since &#8220;sam*&#8221; matches &#8220;sample&#8221;.<\/li>\n<li>The fifth query is a <code>WildcardQuery<\/code> that utilizes a question mark in its search word, &#8220;te?t&#8221;. The question mark can match one character. Since &#8220;te?t&#8221; matches &#8220;test&#8221;, the search returns 1 hit.<\/li>\n<li>The sixth query uses a <code>QueryParser<\/code> with &#8220;te?t&#8221;. The QueryParser <code>parse()<\/code> method returns a <code>WildcardQuery<\/code>, and it gets on hit, just like the fifth query.<\/li>\n<li>The seventh query is a <code>WildcardQuery<\/code> for &#8220;*est&#8221;. It receives one match, since &#8220;test&#8221; matches &#8220;*est&#8221;. In general, it&#8217;s not a good idea to perform queries where the first character is a wildcard.<\/li>\n<li>The eigth query is a <code>QueryParser<\/code> query for &#8220;*est&#8221;. Notice that the <code>QueryParser<\/code> object does not even allow us to perform a query where the first character is an asterisk. It throws a parse exception.<\/li>\n<\/ol>\n<h3><a name=\"boolop\"><\/a>4.3.Boolean Operators<\/h3>\n<p>Boolean operators allow terms to be combined through logic operators. Lucene supports AND, &#8220;+&#8221;, OR, NOT and &#8220;-&#8221; as Boolean operators (Note: Boolean operators must be ALL CAPS).<\/p>\n<p>The OR operator is the default conjunction operator. This means that if there is no Boolean operator between two terms, the OR operator is used. The OR operator links two terms and finds a matching document if either of the terms exist in a document. This is equivalent to a union using sets. The symbol || can be used in place of the word OR.<\/p>\n<p>To search for documents that contain either &#8220;jakarta apache&#8221; or just &#8220;jakarta&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">\"jakarta apache\" jakarta <\/pre>\n<p><strong>or<\/strong><\/p>\n<pre class=\"brush:bash\">\"jakarta apache\" OR jakarta<\/pre>\n<p><strong>AND<\/strong><\/p>\n<p>The AND operator matches documents where both terms exist anywhere in the text of a single document. This is equivalent to an intersection using sets. The symbol &amp;&amp; can be used in place of the word AND.<\/p>\n<p>To search for documents that contain &#8220;jakarta apache&#8221; and &#8220;Apache Lucene&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">\"jakarta apache\" AND \"Apache Lucene\" <\/pre>\n<p><strong>+<\/strong><\/p>\n<p>The &#8220;+&#8221; or required operator requires that the term after the &#8220;+&#8221; symbol exist somewhere in a the field of a single document.<\/p>\n<p>To search for documents that must contain &#8220;jakarta&#8221; and may contain &#8220;lucene&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">+jakarta lucene <\/pre>\n<p><strong>NOT<\/strong><\/p>\n<p>The NOT operator excludes documents that contain the term after NOT. This is equivalent to a difference using sets. The symbol ! can be used in place of the word NOT.<\/p>\n<p>To search for documents that contain &#8220;jakarta apache&#8221; but not &#8220;Apache Lucene&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">\"jakarta apache\" NOT \"Apache Lucene\" <\/pre>\n<p>Note: The NOT operator cannot be used with just one term. For example, the following search will return no results:<\/p>\n<pre class=\"brush:bash\">NOT \"jakarta apache\" <\/pre>\n<p><strong> \u201c-\u201d<\/strong><\/p>\n<p>The &#8220;-&#8221; or prohibit operator excludes documents that contain the term after the &#8220;-&#8221; symbol.<\/p>\n<p>To search for documents that contain &#8220;jakarta apache&#8221; but not &#8220;Apache Lucene&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">\"jakarta apache\" -\"Apache Lucene\" <\/pre>\n<h3><a name=\"grouping\"><\/a>4.3.Grouping<\/h3>\n<p>Lucene supports using parentheses to group clauses to form sub queries. This can be very useful if you want to control the boolean logic for a query.<\/p>\n<p>To search for either &#8220;jakarta&#8221; or &#8220;apache&#8221; and &#8220;website&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">(jakarta OR apache) AND website <\/pre>\n<p>This eliminates any confusion and makes sure you that website must exist and either term jakarta or apache may exist.<\/p>\n<p><b>Field Grouping<\/b><\/p>\n<p>Lucene supports using parentheses to group multiple clauses to a single field.<\/p>\n<p>To search for a title that contains both the word &#8220;return&#8221; and the phrase &#8220;pink panther&#8221; use the query:<\/p>\n<pre class=\"brush:bash\">title:(+return +\"pink panther\") <\/pre>\n<p><b>Escaping Special Characters<\/b><\/p>\n<p>Lucene supports escaping special characters that are part of the query syntax. The current list special characters are:<\/p>\n<p>+ &#8211; &amp;&amp; || ! ( ) { } [ ] ^ &#8221; ~ * ? : \\<\/p>\n<p>To escape these character use &#8220;\\&#8221; (backslash) before the character. For example to search for (1+1):2 use the query:<\/p>\n<pre class=\"brush:bash\">\\\\(1\\\\+1\\\\)\\\\:2 <\/pre>\n<h3><a name=\"phrasequery\"><\/a>4.4.PhraseQuery<\/h3>\n<p>A <code>PhraseQuery<\/code> in Lucene matches documents containing a particular sequence of terms. <code>PhraseQuery<\/code> uses positional information of the term that is stored in an index.<\/p>\n<p>The number of other words permitted between words in query phrase is called &#8220;slop&#8221;. It can be set by calling the setSlop method. If zero, then this is an exact phrase search. For larger values this works like a WITHIN or NEAR operator.<\/p>\n<p>The slop is in fact an edit-distance, where the units correspond to moves of terms in the query phrase out of position. For example, to switch the order of two words requires two moves (the first move places the words atop one another), so to permit re-orderings of phrases, the slop must be at least two.<\/p>\n<p>More exact matches are scored higher than sloppier matches, thus search results are sorted by exactness. The slop is zero by default, requiring exact matches.<\/p>\n<p><code>PhraseQuery<\/code> also supports multiple term phrases.<\/p>\n<p>A Phrase Query may be combined with other terms or queries with a <code>BooleanQuery<\/code>. The maximum number of clauses is restricted to 1,024 by default.<\/p>\n<p>In the previous example of lucene wildcard query, we have done the searching operations based on two text files. Now we will try to find matching phrases using PhraseQuery in lucene.<\/p>\n<p>For that, instead of <code>searchIndexWithWildcardQuery()<\/code> method, we will introduce a new method <code>searchIndexWithPhraseQuery()<\/code> which takes two strings representing words in the document and a slop value. It constructs a <code>PhraseQuery<\/code> by adding two Term objects based on the &#8220;contents&#8221; field and the string1 and string2 parameters. Following that, it sets the slop value of the <code>PhraseQuery<\/code> object using the <code>setSlop()<\/code> method of PhraseQuery. The search is conducted by passing the <code>PhraseQuery<\/code> object to IndexSearcher&#8217;s <code>search()<\/code> method. Here is the code,<\/p>\n<pre class=\"brush:java\">\npublic static void searchIndexWithPhraseQuery(String string1, String string2, int slop) throws IOException,ParseException {\n  Directory directory = \tFSDirectory.getDirectory(INDEX_DIRECTORY);\n  IndexSearcher indexSearcher = new IndexSearcher(directory);\n  Term term1 = new Term(FIELD_CONTENTS, string1);\n  Term term2 = new Term(FIELD_CONTENTS, string2);\n  PhraseQuery phraseQuery = new PhraseQuery();\n  phraseQuery.add(term1);\n  phraseQuery.add(term2);\n  phraseQuery.setSlop(slop);\n  displayQuery(phraseQuery);\n  Hits hits = indexSearcher.search(phraseQuery);\n  displayHits(hits);\n}\n<\/pre>\n<p>And, we call this method from <code>main()<\/code>,<\/p>\n<pre class=\"brush:java\">\n  searchIndexWithPhraseQuery(\"french\", \"fries\", 0);\n  searchIndexWithPhraseQuery(\"hamburger\", \"steak\", 0);\n  searchIndexWithPhraseQuery(\"hamburger\", \"steak\", 1);\n  searchIndexWithPhraseQuery(\"hamburger\", \"steak\", 2);\n  searchIndexWithPhraseQuery(\"hamburger\", \"steak\", 3);\n  searchIndexWithQueryParser(\"french fries\"); \/\/ BooleanQuery\n  searchIndexWithQueryParser(\"\\\\\"french fries\\\\\"\"); \/\/ PhaseQuery\n  searchIndexWithQueryParser(\"\\\\\"hamburger steak\\\\\"~1\"); \/\/ PhaseQuery\n  searchIndexWithQueryParser(\"\\\\\"hamburger steak\\\\\"~2\"); \/\/ PhaseQuery\n<\/pre>\n<p>The first query searches for &#8220;french&#8221; and &#8220;fries&#8221; with a slop of 0, meaning that the phrase search ends up being a search for &#8220;french fries&#8221;, where &#8220;french&#8221; and &#8220;fries&#8221; are next to each other. Since this exists in test-foods.txt, we get 1 hit.<\/p>\n<p>In the second query, we search for &#8220;hamburger&#8221; and &#8220;steak&#8221; with a slop of 0. Since &#8220;hamburger&#8221; and &#8220;steak&#8221; don&#8217;t exist next to each other in either document, we get 0 hits. The third query also involves a search for &#8220;hamburger&#8221; and &#8220;steak&#8221;, but with a slop of 1. These words are not within 1 word of each other, so we get 0 hits.<\/p>\n<p>The fourth query searches for &#8220;hamburger&#8221; and &#8220;steak&#8221; with a slop of 2. In the test-foods.txt file, we have the words &#8220;&#8230; hamburger french fries steak &#8230;&#8221;. Since &#8220;hamburger&#8221; and &#8220;steak&#8221; are within two words of each other, we get 1 hit. The fifth phrase query is the same search but with a slop of 3. Since &#8220;hamburger&#8221; and &#8220;steak&#8221; are withing three words of each other (they are two words from each other), we get a hit of 1.<\/p>\n<p>The next four queries utilize <code>QueryParser<\/code>. Notice that in the first of the <code>QueryParser<\/code> queries, we get a <code>BooleanQuery<\/code> rather than a <code>PhraseQuery<\/code>. This is because we passed QueryParser&#8217;s <code>parse()<\/code> method &#8220;french fries&#8221; rather than &#8220;\\&#8221;french fries\\&#8221;&#8221;. If we want QueryParser to generate a PhraseQuery, the search string needs to be surrounded by double quotes. The next query does search for &#8220;\\&#8221;french fries\\&#8221;&#8221; and we can see that it generates a <code>PhraseQuery<\/code> (with the default slop of 0) and gets 1 hit in response to the query.<\/p>\n<p>The last two <code>QueryParser<\/code> queries demonstrate setting slop values. We can see that the slop values can be set the following the double quotes of the search string with a tilde (~) following by the slop number.<\/p>\n<h3><a name=\"rangequery\"><\/a>4.5.RangeQuery<\/h3>\n<p>A <code>Query<\/code> that matches documents within an exclusive range of terms. It allows one to match documents whose field(s) values are between the lower and upper bound specified by the <code>RangeQuery<\/code>. Range Queries can be inclusive or exclusive of the upper and lower bounds. Sorting is done lexicographically(a collection of items arranged(sorted) in the dictionary order).<\/p>\n<p>Now, if we want to implement <code>RangeQuery<\/code> for Lucene searching operations, we have to add a method named like, <code>searchIndexWithRangeQuery()<\/code>, which is basically a constructor which requires a <code>Term<\/code> indicating the start of the range, a <code>Term<\/code> indicating the end of the range, and a boolean value indicating whether the search is inclusive of the start and end values (&#8220;true&#8221;) or exclusive of the start and end values (&#8220;false&#8221;). The code looks like,<\/p>\n<pre class=\"brush:java\">\npublic static void searchIndexWithRangeQuery(String whichField, String start, String end, boolean inclusive)\n  throws IOException, ParseException {\n  System.out.println(\"\\\\nSearching for range '\" + start + \" to \" + end + \"' using RangeQuery\");\n  Directory directory = FSDirectory.getDirectory(INDEX_DIRECTORY);\n  IndexSearcher indexSearcher = new IndexSearcher(directory);\n  Term startTerm = new Term(whichField, start);\n  Term endTerm = new Term(whichField, end);\n  Query query = new RangeQuery(startTerm, endTerm, inclusive);\n  Hits hits = indexSearcher.search(query);\n  displayHits(hits);\n}\n<\/pre>\n<p>Now we will call the above method,<\/p>\n<pre class=\"brush:java\">\n  searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, \"2014-04-01-00-00-00\", \"2014-04-01-23-59-59\", INCLUSIVE);\n  searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, \"2014-04-02-00-00-00\", \"2014-04-02-23-59-59\", INCLUSIVE);\n  searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, \"2014-04-01-00-00-00\", \"2014-04-01-21-21-02\", INCLUSIVE);\n  searchIndexWithRangeQuery(FIELD_LAST_MODIFIED, \"2014-04-01-00-00-00\", \"2014-04-01-21-21-02\", EXCLUSIVE);\n  \/\/ equivalent range searches using QueryParser\n  searchIndexWithQueryParser(FIELD_LAST_MODIFIED, \"[2014-04-01-00-00-00 TO 2014-04-01-23-59-59]\");\n  searchIndexWithQueryParser(FIELD_LAST_MODIFIED, \"[2014-04-02-00-00-00 TO 2014-04-02-23-59-59]\");\n  searchIndexWithQueryParser(FIELD_LAST_MODIFIED, \"[2014-04-01-00-00-00 TO 2014-04-01-21-21-02]\");\n  searchIndexWithQueryParser(FIELD_LAST_MODIFIED, \"{2014-04-01-00-00-00 TO 2014-04-01-21-21-02}\");\n<\/pre>\n<p>Lastly, there is a little change in <code>createIndex()<\/code> method. We have added some date time realted operations &amp; printed the last modified time of the indexing files.<\/p>\n<p>At the top of the console output, we can see that the two files get indexed, and that the &#8220;last modified&#8221; times for these files are &#8220;2014-04-01-21-21-02&#8221; (for test-foods.txt) and &#8220;2014-04-01-21-21-38&#8221; (for sample-foods.txt).<\/p>\n<p>In the first range query, we search for all files that were last modified on April 1st 2014. This returns 2 hits since both files were last modified on this date. In the second range query, we search for all files that were last modified on April 2nd 2014. This returns 0 hits, since both documents were last modified on April 1st 2014.<\/p>\n<p>Next, we search in a range from 2014-04-01-00-00-00 to 2014-04-01-21-21-02, inclusively. Since test-foods.txt was last modified at 2014-04-01-21-21-02 and the range query includes this value, we get one search hit. Following this, we search in a range from 2014-04-01-00-00-00 to 2014-04-01-21-21-02, exclusively. Since test-foods.txt was last modified at 2014-04-01-21-21-02 and the range query doesn&#8217;t include this value (since it is excluded), this search returns 0 hits.<\/p>\n<p>After this, our next four searches show the equivalent searches performed using a <code>QueryParser<\/code> object. Notice that QueryParser&#8217;s <code>parse()<\/code> method returns a <code>ConstantScoreRangeQuery<\/code> object rather than a <code>RangeQuery<\/code> object for each of these queries, as we can see from the console output for these queries.<\/p>\n<h3><a name=\"prefixquery\"><\/a>4.6.Prefix Query<\/h3>\n<p>A <code>Query<\/code> that matches documents containing terms with a specified prefix. A <code>PrefixQuery<\/code> is built by <code>QueryParser<\/code> for input like nam*.<\/p>\n<p>We will try to search certain term with its prefix using the prefix query using the two text files (test-foods.txt &amp; sample-foods.txt).<\/p>\n<p>For doing that we will add a method named <code>searchIndexWithPrefixQuery()<\/code> which will searche the index (which will be created by <code>createIndex()<\/code>) using a <code>PrefixQuery<\/code>. This method takes two parameters, one is the field name &amp; another is the search string.<\/p>\n<pre class=\"brush:java\">\npublic static void searchIndexWithPrefixQuery(String whichField, String searchString) throws IOException,\n  ParseException {\n  System.out.println(\"\\\\nSearching for '\" + searchString + \"' using PrefixQuery\");\n  Directory directory = FSDirectory.getDirectory(INDEX_DIRECTORY);\n  IndexSearcher indexSearcher = new IndexSearcher(directory);\n  Term term = new Term(whichField, searchString);\n  Query query = new PrefixQuery(term);\n  Hits hits = indexSearcher.search(query);\n  displayHits(hits);\n}\n<\/pre>\n<p>Next we will call this method from <code>main()<\/code> method of program &#8211;<\/p>\n<pre class=\"brush:java\">\n  searchIndexWithPrefixQuery(FIELD_CONTENTS, \"test\");\n  searchIndexWithPrefixQuery(FIELD_CONTENTS, \"tes*\");\n<\/pre>\n<p>In the first query, the query string does not contain an asterisk. So if we print the query type of QueryParser&#8217;s <code>parse()<\/code> method, it will print <code>TermQuery<\/code> instead of <code>PrefixQuery<\/code>.<\/p>\n<p>In the secong query the asterisk indicates to the <code>QueryParser<\/code> that this is a prefix query, so it returns a <code>PrefixQuery<\/code> object from its <code>parse()<\/code> method. This results in a search for the prefix &#8220;tes&#8221; in the indexed contents. This results in 1 hit, since &#8220;test&#8221; is in the index.<\/p>\n<h3><a name=\"fuzzyquery\"><\/a>4.7.Fuzzy Query<\/h3>\n<p>Fuzzy query is based on Damerau-Levenshtein (optimal string alignment) algorithm. <code>FuzzyQuery<\/code> matches terms &#8220;close&#8221; to a specified base term: we specify an allowed maximum edit distance, and any terms within that edit distance from the base term (and, then, the docs containing those terms) are matched.<\/p>\n<p>The <code>QueryParser<\/code> syntax is term~ or term~N, where N is the maximum allowed number of edits (for older releases N was a confusing float between 0.0 and 1.0, which translates to an equivalent max edit distance through a tricky formula).<\/p>\n<p><code>FuzzyQuery<\/code> is great for matching proper names: we can search for lucene~1 and it will match luccene (insert c), lucee (remove n), lukene(replace c with k) and a great many other &#8220;close&#8221; terms. With max edit distance 2 we can have up to 2 insertions, deletions or substitutions. The score for each match is based on the edit distance of that term; so an exact match is scored highest; edit distance 1, lower; etc.<\/p>\n<p><code>QueryParser<\/code> supports fuzzy-term queries using a trailing tilde on a term. For example, searching for wuzza~ will find documents that contain &#8220;fuzzy&#8221; and &#8220;wuzzy&#8221;. Edit distance affects scoring, such that lower edit distances score higher.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a library like this is important and then learn how searching works in Lucene. Moreover, you will learn how to integrate Lucene Search into your own applications in order &hellip;<\/p>\n","protected":false},"author":448,"featured_media":71,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[26],"class_list":["post-44590","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-apache-lucene"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Advanced Lucene Query Examples - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Advanced Lucene Query Examples - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:author\" content=\"http:\/\/www.facebook.com\/phlocblogger\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-27T19:08:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-06T13:42:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-lucene-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Piyas De\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/phloxblog\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Piyas De\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html\"},\"author\":{\"name\":\"Piyas De\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/20f3c9ff4b90d43da03decd2ad2b4f37\"},\"headline\":\"Advanced Lucene Query Examples\",\"datePublished\":\"2015-09-27T19:08:28+00:00\",\"dateModified\":\"2023-12-06T13:42:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html\"},\"wordCount\":3079,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-lucene-logo.jpg\",\"keywords\":[\"Apache Lucene\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html\",\"name\":\"Advanced Lucene Query Examples - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-lucene-logo.jpg\",\"datePublished\":\"2015-09-27T19:08:28+00:00\",\"dateModified\":\"2023-12-06T13:42:41+00:00\",\"description\":\"This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-lucene-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-lucene-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/advanced-lucene-query-examples.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Advanced Lucene Query Examples\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/20f3c9ff4b90d43da03decd2ad2b4f37\",\"name\":\"Piyas De\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eadd6728b7b5be23f0d6585da1a953926e49c6f2369703d6cb4f1147d4dd2203?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eadd6728b7b5be23f0d6585da1a953926e49c6f2369703d6cb4f1147d4dd2203?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eadd6728b7b5be23f0d6585da1a953926e49c6f2369703d6cb4f1147d4dd2203?s=96&d=mm&r=g\",\"caption\":\"Piyas De\"},\"description\":\"Piyas is Sun Microsystems certified Enterprise Architect with 10+ years of professional IT experience in various areas such as Architecture Definition, Define Enterprise Application, Client-server\\\/e-business solutions.Currently he is engaged in providing solutions for digital asset management in media companies.He is also founder and main author of \\\"Technical Blogs(Blog about small technical Know hows)\\\" Hyperlink - http:\\\/\\\/www.phloxblog.in\",\"sameAs\":[\"http:\\\/\\\/www.phloxblog.in\",\"http:\\\/\\\/www.facebook.com\\\/phlocblogger\",\"http:\\\/\\\/in.linkedin.com\\\/in\\\/piyasde\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/phloxblog\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/piyas-de\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Advanced Lucene Query Examples - Java Code Geeks","description":"This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html","og_locale":"en_US","og_type":"article","og_title":"Advanced Lucene Query Examples - Java Code Geeks","og_description":"This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a","og_url":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_author":"http:\/\/www.facebook.com\/phlocblogger","article_published_time":"2015-09-27T19:08:28+00:00","article_modified_time":"2023-12-06T13:42:41+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-lucene-logo.jpg","type":"image\/jpeg"}],"author":"Piyas De","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/phloxblog","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Piyas De","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html"},"author":{"name":"Piyas De","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/20f3c9ff4b90d43da03decd2ad2b4f37"},"headline":"Advanced Lucene Query Examples","datePublished":"2015-09-27T19:08:28+00:00","dateModified":"2023-12-06T13:42:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html"},"wordCount":3079,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-lucene-logo.jpg","keywords":["Apache Lucene"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html","url":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html","name":"Advanced Lucene Query Examples - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-lucene-logo.jpg","datePublished":"2015-09-27T19:08:28+00:00","dateModified":"2023-12-06T13:42:41+00:00","description":"This article is part of our Academy Course titled Apache Lucene Fundamentals. In this course, you will get an introduction to Lucene. You will see why a","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-lucene-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-lucene-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/advanced-lucene-query-examples.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Advanced Lucene Query Examples"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/20f3c9ff4b90d43da03decd2ad2b4f37","name":"Piyas De","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/eadd6728b7b5be23f0d6585da1a953926e49c6f2369703d6cb4f1147d4dd2203?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/eadd6728b7b5be23f0d6585da1a953926e49c6f2369703d6cb4f1147d4dd2203?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/eadd6728b7b5be23f0d6585da1a953926e49c6f2369703d6cb4f1147d4dd2203?s=96&d=mm&r=g","caption":"Piyas De"},"description":"Piyas is Sun Microsystems certified Enterprise Architect with 10+ years of professional IT experience in various areas such as Architecture Definition, Define Enterprise Application, Client-server\/e-business solutions.Currently he is engaged in providing solutions for digital asset management in media companies.He is also founder and main author of \"Technical Blogs(Blog about small technical Know hows)\" Hyperlink - http:\/\/www.phloxblog.in","sameAs":["http:\/\/www.phloxblog.in","http:\/\/www.facebook.com\/phlocblogger","http:\/\/in.linkedin.com\/in\/piyasde","https:\/\/x.com\/https:\/\/twitter.com\/phloxblog"],"url":"https:\/\/www.javacodegeeks.com\/author\/piyas-de"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/44590","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/448"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=44590"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/44590\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/71"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=44590"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=44590"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=44590"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}