public void apply() { for (Map.Entry<DisjunctionMaxQuery, Set<DisjunctionMaxClause>> entry : addenda.entrySet()) { DisjunctionMaxQuery dmq = entry.getKey(); for (DisjunctionMaxClause clause : entry.getValue()) { dmq.addClause(clause); } } addenda.clear(); }
protected void addSynonymTermToDisjunctionMaxQuery(final DisjunctionMaxQuery dmq, final querqy.rewrite.commonrules.model.Term synTerm, final TermMatches termMatches) { final List<String> fieldNames = synTerm.getFieldNames(); final ComparableCharSequence charSequence = synTerm.fillPlaceholders(termMatches); if (fieldNames == null || fieldNames.isEmpty()) { dmq.addClause(new Term(dmq, charSequence, true)); } else { for (final String fieldName: fieldNames) { dmq.addClause(new Term(dmq, fieldName, charSequence, true)); } } }
@Override public BooleanClause clone(final BooleanQuery newParent, final Occur occur, final boolean generated) { final DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(newParent, occur, generated); for (final DisjunctionMaxClause clause : clauses) { dmq.addClause(clause.clone(dmq, generated)); } return dmq; }
@Override public ExpandedQuery rewrite(final ExpandedQuery query) { final QuerqyQuery<?> userQuery = query.getUserQuery(); if (userQuery != null && userQuery instanceof Query){ previousTerm = null; termsToAdd = new LinkedList<>(); visit((Query) userQuery); for (Term term : termsToAdd) { term.getParent().addClause(term); } } return query; }
Query termsToQuery(String termsQuery) { Query query = new Query(); for (String t : termsQuery.split("\\s+")) { if (t.length() > 0) { DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(query, Occur.SHOULD, false); query.addClause(dmq); Term term = new Term(dmq, t); dmq.addClause(term); } } return query; }
@Override public DisjunctionMaxQuery visit(final DisjunctionMaxQuery disjunctionMaxQuery) { final DisjunctionMaxQuery newDMQ = new DisjunctionMaxQuery((BooleanQuery) getNewParent(), disjunctionMaxQuery.occur, true); newParentStack.add(newDMQ); for (final DisjunctionMaxClause clause : disjunctionMaxQuery.getClauses()) { newDMQ.addClause((DisjunctionMaxClause) clause.accept(this)); } newParentStack.removeLast(); return newDMQ; }
@Override public DisjunctionMaxQuery visit(final DisjunctionMaxQuery disjunctionMaxQuery) { boolean hasPlaceHolderChild = false; final List<DisjunctionMaxClause> oldClauses = disjunctionMaxQuery.getClauses(); final List<DisjunctionMaxClause> newClauses = new ArrayList<>(oldClauses.size()); for (final DisjunctionMaxClause clause : oldClauses) { final DisjunctionMaxClause mayBeRewritten = (DisjunctionMaxClause) clause.accept(this); newClauses.add(mayBeRewritten); hasPlaceHolderChild |= (mayBeRewritten != clause); } if (hasPlaceHolderChild) { for (final DisjunctionMaxClause clause : oldClauses) { disjunctionMaxQuery.removeClause(clause); } for (final DisjunctionMaxClause clause : newClauses) { disjunctionMaxQuery.addClause(clause); } hasPlaceHolder = true; } return disjunctionMaxQuery; }
@Override public ExpandedQuery rewrite(final ExpandedQuery query) { final QuerqyQuery<?> userQuery = query.getUserQuery(); if (userQuery instanceof Query){ previousTerms = new ArrayDeque<>(); termsToDelete = new ArrayDeque<>(); nodesToAdd = new LinkedList<>(); visit((Query) userQuery); // append nodesToAdd to parent query nodesToAdd.forEach(node -> { final Node parent = node.getParent(); // TODO: extend BooleanParent? interface so that we don't need this cast? if (parent instanceof DisjunctionMaxQuery) { ((DisjunctionMaxQuery) parent).addClause((DisjunctionMaxClause) node); } else if (parent instanceof BooleanQuery) { ((BooleanQuery) parent).addClause((BooleanClause) node); } else { throw new IllegalStateException("Unknown parent type " + parent.getClass().getName()); } }); termsToDelete.forEach(this::removeIfNotOnlyChild); } return query; }
/** * Add terms to the query for the synonyms. * * @param dmq * {@link DisjunctionMaxQuery} * @param original * Original term to determine synonyms for. */ private void addSynonyms(DisjunctionMaxQuery dmq, CharSequence original) throws IOException { try (TokenStream synonymTokens = optSynonymAnalyzer.tokenStream("querqy", new CharSequenceReader(original))) { synonymTokens.reset(); CharTermAttribute generated = synonymTokens.addAttribute(CharTermAttribute.class); while (synonymTokens.incrementToken()) { // We need to copy "generated" per toString() here, because // "generated" is transient. dmq.addClause(new Term(dmq, generated.toString(), true)); } synonymTokens.end(); } }
protected void decompound(final Term term) { // determine the nodesToAdd based on the term try { for (final SuggestWord[] decompounded : suggestWordbreaks(term)) { if (decompounded != null && decompounded.length > 0) { final BooleanQuery bq = new BooleanQuery(term.getParent(), Clause.Occur.SHOULD, true); for (final SuggestWord word : decompounded) { final DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(bq, Clause.Occur.MUST, true); bq.addClause(dmq); dmq.addClause(new Term(dmq, term.getField(), word.string, true)); } nodesToAdd.add(bq); } } } catch (final IOException e) { // IO is broken, this looks serious -> throw as RTE throw new RuntimeException("Error decompounding " + term, e); } }
private void addTerm(Query query, String field, String value) { DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(query, Clause.Occur.SHOULD, true); query.addClause(dmq); Term term = new Term(dmq, field, value); dmq.addClause(term); }
private void addTerm(Query query, String field, String value, boolean isGenerated) { DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(query, Clause.Occur.SHOULD, true); query.addClause(dmq); Term term = new Term(dmq, field, value, isGenerated); dmq.addClause(term); }
newDmq.addClause(new Term(newDmq, new SimpleComparableCharSequence(scratchChars, start, i - start), true)); add.addClause(newDmq); if (start < scratchChars.length) { DisjunctionMaxQuery newDmq = new DisjunctionMaxQuery(add, Occur.MUST, true); newDmq.addClause(new Term(newDmq, new SimpleComparableCharSequence(scratchChars, start, scratchChars.length - start), true)); add.addClause(newDmq);
@Override public Node visitTermQuery(TermQueryContext ctx) { BooleanQuery parent = booleanQueryStack.getLast(); DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(parent, getOccur(), false); TermContext tc = ctx.getRuleContext(TermContext.class, 0); Token startToken = tc.getStart(); List<FieldNameContext> fieldNameContexts = ctx.getRuleContexts(FieldNameContext.class); if (fieldNameContexts != null && !fieldNameContexts.isEmpty()) { for (FieldNameContext fieldNameContext : fieldNameContexts) { String fieldName = fieldNameContext.getText(); dmq.addClause( new Term(dmq, fieldName, new SimpleComparableCharSequence(input, startToken.getStartIndex(), 1 + startToken.getStopIndex() - startToken.getStartIndex()))); } } else { dmq.addClause(new Term(dmq, new SimpleComparableCharSequence(input, startToken.getStartIndex(), 1 + startToken.getStopIndex() - startToken.getStartIndex()))); } parent.addClause(dmq); return dmq; }
if (scratchChars[i] == ' ' && (i > start)) { DisjunctionMaxQuery newDmq = new DisjunctionMaxQuery(replaceSeq, Occur.MUST, true); newDmq.addClause( new Term(newDmq, new SimpleComparableCharSequence(scratchChars, start, i - start))); newDmq.addClause(new Term(newDmq, new SimpleComparableCharSequence(scratchChars, start, scratchChars.length - start))); replaceSeq.addClause(newDmq); replaceDmq.addClause(new Term(replaceDmq, new SimpleComparableCharSequence(scratchChars, 0, scratchChars.length))); add.addClause(replaceDmq); neqDmq.addClause(negTerm.clone(neqDmq, true)); neq.addClause(neqDmq);
@Test public void testThatTermIsRemovedIfThereIsAnotherTermInTheSameDMQ() throws Exception { RulesCollectionBuilder builder = new TrieMapRulesCollectionBuilder(false); DeleteInstruction delete = new DeleteInstruction(Arrays.asList(mkTerm("a"))); builder.addRule(new Input(Arrays.asList(mkTerm("a")), false, false), new Instructions(Arrays.asList((Instruction) delete))); RulesCollection rules = builder.build(); CommonRulesRewriter rewriter = new CommonRulesRewriter(rules); ExpandedQuery expandedQuery = makeQuery("a"); Query query = (Query) expandedQuery.getUserQuery(); DisjunctionMaxQuery dmq = query.getClauses(DisjunctionMaxQuery.class).get(0); querqy.model.Term termB = new querqy.model.Term(dmq, null, "b"); dmq.addClause(termB); Query rewritten = (Query) rewriter.rewrite(expandedQuery, EMPTY_CONTEXT).getUserQuery(); assertThat(rewritten, bq( dmq( term("b") ) )); }
@Test public void testThatTermIsRemovedOnceIfItExistsTwiceInSameDMQAndNoOtherTermExistsInQuery() throws Exception { RulesCollectionBuilder builder = new TrieMapRulesCollectionBuilder(false); DeleteInstruction delete = new DeleteInstruction(Arrays.asList(mkTerm("a"))); builder.addRule(new Input(Arrays.asList(mkTerm("a")), false, false), new Instructions(Arrays.asList((Instruction) delete))); RulesCollection rules = builder.build(); CommonRulesRewriter rewriter = new CommonRulesRewriter(rules); ExpandedQuery expandedQuery = makeQuery("a"); Query query = (Query) expandedQuery.getUserQuery(); DisjunctionMaxQuery dmq = query.getClauses(DisjunctionMaxQuery.class).get(0); querqy.model.Term termB = new querqy.model.Term(dmq, null, "a"); dmq.addClause(termB); Query rewritten = (Query) rewriter.rewrite(expandedQuery, EMPTY_CONTEXT).getUserQuery(); assertThat(rewritten, bq( dmq( term("a") ) )); }
@Test public void testThatGeneratedIsPropagatedToClauses() throws Exception { BooleanQuery bq = new BooleanQuery(null, SHOULD, false); DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(bq, Clause.Occur.SHOULD, false); bq.addClause(dmq); dmq.addClause(new Term(dmq, "Test", false)); final BooleanQuery clone = (BooleanQuery) bq.clone(null, MUST, true); assertThat(clone, bq(must(), dmq(should(), term("Test", true)))); assertTrue(clone.isGenerated()); assertTrue(clone.getClauses().get(0).isGenerated()); assertEquals(MUST, clone.getOccur()); } }