2015-05-22 2 views
1

Мне нужно выбрать все документы, которые не имеют определенного поля, и имеют правильное значение для одного поля. Я стараюсь избегать использования строки «null» в качестве значения для полей, которые являются нулевыми, поэтому по lucene эти поля не сохраняются для этих документов.Lucene: Поиск документов, которые не имеют определенного поля

Структура документа выглядит следующим образом

class familyMember { 
    String id; 
    String name; 
    String parentId; // Id of familyMember object which is parent of this member 
} 

То, что я хочу, чтобы получить все familyMembers, которые не имеют родителей. Поэтому давайте скажем корень дерева, если вы посмотрите на это так.

Я перепробовал много способов, но это выглядит, как наилучшим образом:

if (parentId != null) { 
    Query parentIdQuery = new TermQuery(new Term("parentID", parentId.toString())); 
    booleanQuery.add(parentIdQuery, BooleanClause.Occur.MUST); 
} else { 
    QueryParser queryParser = new QueryParser(LUCENE_VERSION, "parentId"), analyzer); 
    queryParser.setAllowLeadingWildcard(true); 
    Query parentIdQuery = queryParser.parse("%%"); 
    booleanQuery.add(parentIdQuery, BooleanClause.Occur.MUST_NOT); 
} 

Но по какой-то причине, каждый раз, когда я пытаюсь этот запрос, я получаю все familyMambers, которые не имеют родителей, кроме одного! И какая бы ни была древовидная структура, которую я стараюсь в конце, я заканчиваю только ОДИН член, у которого есть родитель ...

Кто-нибудь знает, что я делаю неправильно, или знает лучший способ найти документы, которые не имеют одного поле?

Я использую booleanQuery, потому что после этого у меня есть проверка, хочет ли пользователь больше условий, например, получить мне всех членов, у которых нет родителя, и имеет имя типа «Билл».

EDIT 1: Я тоже пробовал этот, но опять же проблема.

if (parentId != null) { 
    Query parentIdQuery = new TermQuery(new Term("parentID", parentId.toString())); 
    booleanQuery.add(parentIdQuery, BooleanClause.Occur.MUST); 
} else { 
    Query parentIdQuery = new TermQuery(new Term("parentID", "%%")); 
    booleanQuery.add(parentIdQuery, BooleanClause.Occur.MUST_NOT); 
} 

ответ

0

Хорошо, я нашел решение. Трюк был в

new ConstantScoreQuery(new FieldValueFilter()); 

Solution:

if (parentId != null) { 
    Query parentIdQuery = new TermQuery(new Term("parentID", parentId.toString())); 
    booleanQuery.add(parentIdQuery, BooleanClause.Occur.MUST); 
} else { 
    Query parentIdQuery = new ConstantScoreQuery(new FieldValueFilter("parentID", true)); 
    booleanQuery.add(parentIdQuery, BooleanClause.Occur.MUST); 

}

Смежные вопросы