<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Today, in Hibernate Search, a query is applied on all shards. We use a MultiReader to wrap them together.<div>In some sharding scenario, it makes sense to apply the query on a single shard or a subset of the shards.</div><div><br></div><div>We could add the following API to IndexShardingStrategy</div><div><br></div><div>public DirectoryProvider<?>[] <span class="Apple-style-span" style="font-family: Monaco; font-size: 11px; ">getDirectoryProvidersForQuery(o.a.l.search.Query query);</span></div><div><br></div><div>The query could be analyzed by the sharding strategy to detect boolean queries on their sharding criteria</div><div><br></div><div>//query building</div><div>BooleanQuery bQuery = new BooleanQuery();</div><div>bQuery.add(regularQuery, Occur.MUST);</div><div>bQuery.add( new TermQuery( new Term("distributor.id", "2"), Occur.MUST ); //only occurs in shard 1</div><div><br></div><div>public DirectoryProvider<?>[] <span class="Apple-style-span" style="font-family: Monaco; font-size: 11px; ">getDirectoryProvidersForQuery(o.a.l.search.Query query) {</span></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> if (query instanceof BooleanQuery) {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> List<BooleanClause> clauses = BooleanQuery.class.cast(query).clauses</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> int restrictedShard;</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> boolean isAllMust = true;</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> for (BooleanClause clause : clauses) {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> if (clause.getOccur() != Occur.MUST) { isAllMust = false; break; }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> if ( clause.getQuery() instanceof TermQuery ) {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> Term term = TermQuery.class.cast( clause.getQuery() ).getTerm();</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> if (term.field().equals("distributor.id")) { restrictedShard = Integer.parse(term.text(); }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> if (isAllMust && restrictedShard != null) return new Provider[] { providers[restrictedShard-1] };</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> else return providers;</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">}</span></font></div><div><br></div><div><br></div><div>That's very flexibile but quite hard to implement correctly especially since the query tree structure might not be trivial</div><div><br></div><div>The alternative strategy is to have the following API on IndexShardingStrategy</div><div><br></div><div>public DirectoryProvider<?>[] <span class="Apple-style-span" style="font-family: Monaco; font-size: 11px; ">getDirectoryProvidersForQuery(Object hint);</span></div><div><br></div><div>and a corresponding fullTextQuery.setShardHint(Object);</div><div><br></div><div>A query could "know it targets shard 2 and pass the information to the strategy through a standard language:</div><div><br></div><div>fullTextQuery.setShardHint("Sony");</div><div><br></div><div>public DirectoryProvider<?>[] <span class="Apple-style-span" style="font-family: Monaco; font-size: 11px; ">getDirectoryProvidersForQuery(Object hint) {</span></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> if (String.class.isInstance(hint) && String.class.cast(hint).equals("Sony")) {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> return new Provider[] { providers[2] }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> else {</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> return providers;</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;"> }</span></font></div><div><font class="Apple-style-span" face="Monaco" size="3"><span class="Apple-style-span" style="font-size: 11px;">}</span></font></div><div><br></div><div>WDYT? How useful would that be?<br><div> <span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>--</div><div><div>Emmanuel Bernard</div><div><a href="http://in.relation.to/Bloggers/Emmanuel">http://in.relation.to/Bloggers/Emmanuel</a> | <a href="http://blog.emmanuelbernard.com/">http://blog.emmanuelbernard.com</a> | <a href="http://twitter.com/emmanuelbernard">http://twitter.com/emmanuelbernard</a></div><div>Hibernate Search in Action (<a href="http://is.gd/Dl1">http://is.gd/Dl1</a>)</div></div></div></span></div></span></div></span> </div><br></div></body></html>