下面列出了怎么用org.apache.lucene.search.DocValuesFieldExistsQuery的API类实例代码及写法,或者点击链接到github查看源代码。
private static void checkSoftDeletes(String softDeletesField, SegmentCommitInfo info, SegmentReader reader, PrintStream infoStream, boolean failFast) throws IOException {
if (infoStream != null)
infoStream.print(" test: check soft deletes.....");
try {
int softDeletes = PendingSoftDeletes.countSoftDeletes(DocValuesFieldExistsQuery.getDocValuesDocIdSetIterator(softDeletesField, reader), reader.getLiveDocs());
if (softDeletes != info.getSoftDelCount()) {
throw new RuntimeException("actual soft deletes: " + softDeletes + " but expected: " +info.getSoftDelCount());
}
} catch (Exception e) {
if (failFast) {
throw IOUtils.rethrowAlways(e);
}
msg(infoStream, "ERROR [" + String.valueOf(e.getMessage()) + "]");
if (infoStream != null) {
e.printStackTrace(infoStream);
}
}
}
@Override
protected Query filterQuery(LongRange groupValue) {
if (groupValue == null) {
return new BooleanQuery.Builder()
.add(new MatchAllDocsQuery(), BooleanClause.Occur.FILTER)
.add(new DocValuesFieldExistsQuery("long"), BooleanClause.Occur.MUST_NOT)
.build();
}
return LongPoint.newRangeQuery("long", groupValue.min, groupValue.max - 1);
}
@Override
protected Query filterQuery(DoubleRange groupValue) {
if (groupValue == null) {
return new BooleanQuery.Builder()
.add(new MatchAllDocsQuery(), BooleanClause.Occur.FILTER)
.add(new DocValuesFieldExistsQuery("double"), BooleanClause.Occur.MUST_NOT)
.build();
}
return DoublePoint.newRangeQuery("double", groupValue.min, Math.nextDown(groupValue.max));
}
@Override
protected Query filterQuery(BytesRef groupValue) {
if (groupValue == null) {
return new BooleanQuery.Builder()
.add(new MatchAllDocsQuery(), BooleanClause.Occur.FILTER)
.add(new DocValuesFieldExistsQuery("groupField"), BooleanClause.Occur.MUST_NOT)
.build();
}
return new TermQuery(new Term("groupField", groupValue));
}
@Override
public Query rewrite(IndexReader reader) throws IOException {
if (lowerValue == null && upperValue == null) {
return new DocValuesFieldExistsQuery(field);
}
return super.rewrite(reader);
}
@Override
public Query rewrite(IndexReader reader) throws IOException {
if (lowerValue == Long.MIN_VALUE && upperValue == Long.MAX_VALUE) {
return new DocValuesFieldExistsQuery(field);
}
return super.rewrite(reader);
}
private DocSet resolveLeafNodes() throws IOException {
String field = collectSchemaField.getName();
BooleanQuery.Builder leafNodeQuery = new BooleanQuery.Builder();
Query edgeQuery = collectSchemaField.hasDocValues() ? new DocValuesFieldExistsQuery(field) : new WildcardQuery(new Term(field, "*"));
leafNodeQuery.add(edgeQuery, Occur.MUST_NOT);
DocSet leafNodes = fromSearcher.getDocSet(leafNodeQuery.build());
return leafNodes;
}
private Query getRangeQueryInternal(QParser parser, SchemaField field, final CurrencyValue p1, final CurrencyValue p2, final boolean minInclusive, final boolean maxInclusive) {
String currencyCode = (p1 != null) ? p1.getCurrencyCode() :
(p2 != null) ? p2.getCurrencyCode() : defaultCurrency;
// ValueSourceRangeFilter doesn't check exists(), so we have to
final Query docsWithValues = new DocValuesFieldExistsQuery(getAmountField(field).getName());
final Query vsRangeFilter = new ValueSourceRangeFilter
(new RawCurrencyValueSource(field, currencyCode, parser),
p1 == null ? null : p1.getAmount() + "",
p2 == null ? null : p2.getAmount() + "",
minInclusive, maxInclusive);
return new ConstantScoreQuery(new BooleanQuery.Builder()
.add(docsWithValues, Occur.FILTER)
.add(vsRangeFilter, Occur.FILTER).build());
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else if (omitNorms()) {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
} else {
return new NormsFieldExistsQuery(name());
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
@Override
public Query existsQuery(QueryShardContext context) {
if (hasDocValues()) {
return new DocValuesFieldExistsQuery(name());
} else {
return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name()));
}
}
public void testSoftDeleteWhileMergeSurvives() throws IOException {
Directory dir = newDirectory();
String softDelete = "soft_delete";
IndexWriterConfig config = newIndexWriterConfig().setSoftDeletesField(softDelete);
AtomicBoolean update = new AtomicBoolean(true);
config.setReaderPooling(true);
config.setMergePolicy(new SoftDeletesRetentionMergePolicy("soft_delete", () -> new DocValuesFieldExistsQuery("keep"),
new LogDocMergePolicy()));
IndexWriter writer = new IndexWriter(dir, config);
writer.getConfig().setMergedSegmentWarmer(sr -> {
if (update.compareAndSet(true, false)) {
try {
writer.softUpdateDocument(new Term("id", "0"), new Document(),
new NumericDocValuesField(softDelete, 1), new NumericDocValuesField("keep", 1));
writer.commit();
} catch (IOException e) {
throw new AssertionError(e);
}
}
});
boolean preExistingDeletes = random().nextBoolean();
for (int i = 0; i < 2; i++) {
Document d = new Document();
d.add(new StringField("id", Integer.toString(i), Field.Store.YES));
if (preExistingDeletes && random().nextBoolean()) {
writer.addDocument(d); // randomly add a preexisting hard-delete that we don't carry over
writer.deleteDocuments(new Term("id", Integer.toString(i)));
d.add(new NumericDocValuesField("keep", 1));
writer.addDocument(d);
} else {
d.add(new NumericDocValuesField("keep", 1));
writer.addDocument(d);
}
writer.flush();
}
writer.forceMerge(1);
writer.commit();
assertFalse(update.get());
DirectoryReader open = DirectoryReader.open(dir);
assertEquals(0, open.numDeletedDocs());
assertEquals(3, open.maxDoc());
IOUtils.close(open, writer, dir);
}
@Test
public void testFieldExistsQueries() throws SyntaxError {
SolrQueryRequest req = req();
String[] fieldSuffix = new String[] {
"ti", "tf", "td", "tl", "tdt",
"pi", "pf", "pd", "pl", "pdt",
"i", "f", "d", "l", "dt", "s", "b",
"is", "fs", "ds", "ls", "dts", "ss", "bs",
"i_dv", "f_dv", "d_dv", "l_dv", "dt_dv", "s_dv", "b_dv",
"is_dv", "fs_dv", "ds_dv", "ls_dv", "dts_dv", "ss_dv", "bs_dv",
"i_dvo", "f_dvo", "d_dvo", "l_dvo", "dt_dvo",
"t",
"t_on", "b_norms", "s_norms", "dt_norms", "i_norms", "l_norms", "f_norms", "d_norms"
};
String[] existenceQueries = new String[] {
"*", "[* TO *]"
};
for (String existenceQuery : existenceQueries) {
for (String suffix : fieldSuffix) {
IndexSchema indexSchema = h.getCore().getLatestSchema();
String field = "foo_" + suffix;
String query = field + ":" + existenceQuery;
QParser qParser = QParser.getParser(query, req);
Query createdQuery = qParser.getQuery();
SchemaField schemaField = indexSchema.getField(field);
// Test float & double realNumber queries differently
if ("[* TO *]".equals(existenceQuery) && (schemaField.getType().getNumberType() == NumberType.DOUBLE || schemaField.getType().getNumberType() == NumberType.FLOAT)) {
assertFalse("For float and double fields \"" + query + "\" is not an existence query, so the query returned should not be a DocValuesFieldExistsQuery.", createdQuery instanceof DocValuesFieldExistsQuery);
assertFalse("For float and double fields \"" + query + "\" is not an existence query, so the query returned should not be a NormsFieldExistsQuery.", createdQuery instanceof NormsFieldExistsQuery);
assertFalse("For float and double fields \"" + query + "\" is not an existence query, so NaN should not be matched via a ConstantScoreQuery.", createdQuery instanceof ConstantScoreQuery);
assertFalse("For float and double fields\"" + query + "\" is not an existence query, so NaN should not be matched via a BooleanQuery (NaN and [* TO *]).", createdQuery instanceof BooleanQuery);
} else {
if (schemaField.hasDocValues()) {
assertTrue("Field has docValues, so existence query \"" + query + "\" should return DocValuesFieldExistsQuery", createdQuery instanceof DocValuesFieldExistsQuery);
} else if (!schemaField.omitNorms() && !schemaField.getType().isPointField()) { //TODO: Remove !isPointField() for SOLR-14199
assertTrue("Field has norms and no docValues, so existence query \"" + query + "\" should return NormsFieldExistsQuery", createdQuery instanceof NormsFieldExistsQuery);
} else if (schemaField.getType().getNumberType() == NumberType.DOUBLE || schemaField.getType().getNumberType() == NumberType.FLOAT) {
assertTrue("PointField with NaN values must include \"exists or NaN\" if the field doesn't have norms or docValues: \"" + query + "\".", createdQuery instanceof ConstantScoreQuery);
assertTrue("PointField with NaN values must include \"exists or NaN\" if the field doesn't have norms or docValues: \"" + query + "\".", ((ConstantScoreQuery)createdQuery).getQuery() instanceof BooleanQuery);
assertEquals("PointField with NaN values must include \"exists or NaN\" if the field doesn't have norms or docValues: \"" + query + "\". This boolean query must be an OR.", 1, ((BooleanQuery)((ConstantScoreQuery)createdQuery).getQuery()).getMinimumNumberShouldMatch());
assertEquals("PointField with NaN values must include \"exists or NaN\" if the field doesn't have norms or docValues: \"" + query + "\". This boolean query must have 2 clauses.", 2, ((BooleanQuery)((ConstantScoreQuery)createdQuery).getQuery()).clauses().size());
} else {
assertFalse("Field doesn't have docValues, so existence query \"" + query + "\" should not return DocValuesFieldExistsQuery", createdQuery instanceof DocValuesFieldExistsQuery);
assertFalse("Field doesn't have norms, so existence query \"" + query + "\" should not return NormsFieldExistsQuery", createdQuery instanceof NormsFieldExistsQuery);
}
}
}
}
}
@Override
public Query existsQuery(QueryShardContext context) {
return new DocValuesFieldExistsQuery(name());
}
@Override
public Query existsQuery(QueryShardContext context) {
return new DocValuesFieldExistsQuery(name());
}
/**
* Returns a Query instance for doing existence searches for a field.
* If the field does not have docValues or norms, this method will call {@link #getSpecializedExistenceQuery}, which defaults to an unbounded rangeQuery.
* <p>
* This method should only be overriden whenever a fieldType does not support {@link org.apache.lucene.search.DocValuesFieldExistsQuery} or {@link org.apache.lucene.search.NormsFieldExistsQuery}.
* If a fieldType does not support an unbounded rangeQuery as an existenceQuery (such as <code>double</code> or <code>float</code> fields), {@link #getSpecializedExistenceQuery} should be overriden.
*
* @param parser The {@link org.apache.solr.search.QParser} calling the method
* @param field The {@link org.apache.solr.schema.SchemaField} of the field to search
* @return The {@link org.apache.lucene.search.Query} instance.
*/
public Query getExistenceQuery(QParser parser, SchemaField field) {
if (field.hasDocValues()) {
return new DocValuesFieldExistsQuery(field.getName());
} else if (!field.omitNorms() && !isPointField()) { //TODO: Remove !isPointField() for SOLR-14199
return new NormsFieldExistsQuery(field.getName());
} else {
// Default to an unbounded range query
return getSpecializedExistenceQuery(parser, field);
}
}