Filter nullFilter = null;
MapperService.SmartNameFieldMappers nonNullFieldMappers = null;
if (existence) {
XBooleanFilter boolFilter = new XBooleanFilter();
for (String field : fields) {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(field);
if (smartNameFieldMappers != null) {
nonNullFieldMappers = smartNameFieldMappers;
}
Filter filter = null;
if (fieldNamesMapper != null && fieldNamesMapper.mapper().fieldType().indexOptions() != IndexOptions.NONE) {
final String f;
if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
f = smartNameFieldMappers.mapper().names().indexName();
} else {
f = field;
}
filter = fieldNamesMapper.mapper().termFilter(f, parseContext);
}
// if _field_names are not indexed, we need to go the slow way
if (filter == null && smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext);
}
if (filter == null) {
filter = new TermRangeFilter(field, null, null, true, true);
}
boolFilter.add(filter, BooleanClause.Occur.SHOULD);
}
// we always cache this one, really does not change... (exists)
// its ok to cache under the fieldName cacheKey, since its per segment and the mapping applies to this data on this segment...
existenceFilter = parseContext.cacheFilter(boolFilter, new CacheKeyFilter.Key("$exists$" + fieldPattern));
existenceFilter = new NotFilter(existenceFilter);
// cache the not filter as well, so it will be faster
existenceFilter = parseContext.cacheFilter(existenceFilter, new CacheKeyFilter.Key("$missing$" + fieldPattern));
}
if (nullValue) {
for (String field : fields) {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(field);
if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
nullFilter = smartNameFieldMappers.mapper().nullValueFilter();
if (nullFilter != null) {
// cache the not filter as well, so it will be faster
nullFilter = parseContext.cacheFilter(nullFilter, new CacheKeyFilter.Key("$null$" + fieldPattern));
}
}
}
}
Filter filter;
if (nullFilter != null) {
if (existenceFilter != null) {
XBooleanFilter combined = new XBooleanFilter();
combined.add(existenceFilter, BooleanClause.Occur.SHOULD);
combined.add(nullFilter, BooleanClause.Occur.SHOULD);
// cache the not filter as well, so it will be faster
filter = parseContext.cacheFilter(combined, null);
} else {
filter = nullFilter;
}