Я заполнил индекс родительскими и дочерними документами, используя «Блоки». то есть документы добавляются с использованием метода IndexWriter.addAll (), причем последний документ является родительским документом.
На данный момент мне удалось найти только «блоки», в результате чего любые термины в запросе отображаются либо в родительском, либо в дочернем. Это дает мне искаженные результаты. например Я получаю лучшие результаты, когда один из терминов многократно встречается в блоке, но другие термины не отображаются вообще.
Я хочу найти «Блоки», в результате чего все термины в запросе должны появляться либо в родительском, либо в дочернем.
Но я не уверен, как построить запрос.
Мой текущий код запроса выглядит следующим образом:
Analyzer analyzer = new EnglishAnalyzer();
//Note, both parent and child docs have a 'textContent' field
QueryParser queryParser = new QueryParser("textContent", analyzer);
Directory index = FSDirectory.open(Paths.get("${indexParentDir}/${name}.lucene"));
BitSetProducer parentsFilter = new QueryBitSetProducer(new TermQuery(new Term("child", "N")));
Query textQuery = queryParser.parse("foo bar");
//Construct child query
BooleanQuery.Builder childQueryBuilder = new BooleanQuery.Builder();
childQueryBuilder.add(new BooleanClause(textQuery, BooleanClause.Occur.MUST));
childQueryBuilder.add(new BooleanClause(new TermQuery(new Term("child", "Y")), BooleanClause.Occur.MUST));
Query childQuery = new ToParentBlockJoinQuery(childQueryBuilder.build(), parentsFilter, ScoreMode.Avg);
//Construct parent query
BooleanQuery.Builder parentQueryBuilder = new BooleanQuery.Builder();
parentQueryBuilder.add(new BooleanClause(textQuery, BooleanClause.Occur.MUST));
parentQueryBuilder.add(new BooleanClause(new TermQuery(new Term("child", "N")), BooleanClause.Occur.MUST));
//Construct join of child and parent query
BooleanQuery.Builder childAndParentQueryBuilder = new BooleanQuery.Builder();
childAndParentQueryBuilder.add(new BooleanClause(childQuery, BooleanClause.Occur.SHOULD));
childAndParentQueryBuilder.add(new BooleanClause(parentQueryBuilder.build(), BooleanClause.Occur.SHOULD));
Query childAndParentQuery = childAndParentQueryBuilder.build();
//Run the query
DirectoryReader reader = DirectoryReader.open(index);
CheckJoinIndex.check(reader, parentsFilter);
IndexSearcher searcher = new IndexSearcher(reader);
searcher.search(childAndParentQuery, 10);
Приведенный выше код вернет лучшие результаты, в результате чего один из терминов встречается много раз. например Если 'foo' появляется 100 раз в родительских или дочерних документах. Но «бар» вообще не появляется.
Я хотел бы вернуть только результаты, при которых все термины (например, 'foo' и 'bar') появляются либо в родительском, либо в одном из его дочерних элементов.
Один из вариантов - создать поле в родительских документах, которое представляет собой объединение всех полей textContent в родительских и дочерних документах и выполнять поиск только в новом агрегированном поле. Но эти показатели уже довольно велики. (например, 50 ГБ). И я все еще должен хранить textContent отдельно для родительских и дочерних элементов для отображения, поэтому создание агрегированного поля почти удвоит размер индекса.
Буду признателен за любую помощь.