Использование полей XML для поиска расплывчатости в Lucene - PullRequest
2 голосов
/ 11 октября 2011

У меня есть набор документов, который выглядит следующим образом:

<doc>
text sample text <x>text</x> words lipsum words words <x>text</x> some other text
</doc>

Я хотел бы иметь возможность искать фразы (""), которые встречаются в определенном количестве токенов из аннотации.Как я могу индексировать и искать, как это?

1 Ответ

1 голос
/ 13 января 2012

Вы можете использовать собственный анализатор для анализа вашего потока XML. Я взломал тот, который разделяется на пробелы, '>' и '/', так что токены XML идентифицируются как '

public class SpanQueryTests {
    private IndexSearcher searcher;
    private IndexReader reader;
    private Analyzer analyzer;

    static class XMLTokenizer extends CharTokenizer {
        public XMLTokenizer(Reader input) {
            super(input);
        }

        final static Set<Character> chars = ImmutableSet.of('/', '>');

        @Override
        protected boolean isTokenChar(char c) {
            return !(Character.isWhitespace(c) || chars.contains(c));
        }
    }

    @Before
    public void setUp() throws Exception {
        Directory dir = new RAMDirectory();
        analyzer = new Analyzer() {
            @Override
            public TokenStream tokenStream(String fieldName, Reader reader) {
                return new XMLTokenizer(reader);
            }

            @Override
            public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException {
                Tokenizer tokenizer = (Tokenizer) getPreviousTokenStream();
                if (tokenizer == null) {
                    tokenizer = new XMLTokenizer(reader);
                    setPreviousTokenStream(tokenizer);
                } else
                    tokenizer.reset(reader);
                return tokenizer;
            }
        };
        IndexWriter writer = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
        ImmutableList<String> docs = ImmutableList.of("<doc>text sample text <x>test</x> words lipsum words words " +
                                                              "<x>text</x> some other text </doc>",
                                                             "<foobar>test</foobar> some more text flop");
        int id = 0;
        for (String content: docs) {
            Document doc = new Document();
            doc.add(new Field("id", String.valueOf(id++), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED));
            writer.addDocument(doc);
            id++;
        }
        writer.close();

        searcher = new IndexSearcher(dir);
        reader = searcher.getIndexReader();
    }

    @After
    public void tearDown() throws Exception {
        searcher.close();
    }

    @Test
    public void testTermNearQuery() throws Exception {
        SpanTermQuery tq1 = new SpanTermQuery(new Term("content", "lipsum"));
        dumpSpans(tq1);
        SpanTermQuery tq2 = new SpanTermQuery(new Term("content", "other"));
        dumpSpans(tq2);
        SpanTermQuery tq3 = new SpanTermQuery(new Term("content", "<x"));
        dumpSpans(tq3);
        SpanNearQuery snq1 = new SpanNearQuery(new SpanQuery[] { tq1, tq3 }, 2, false);
        dumpSpans(snq1);
        SpanNearQuery snq2 = new SpanNearQuery(new SpanQuery[] { tq2, tq3 }, 2, false);
        dumpSpans(snq2);
    }
}

Результаты:

query content:lipsum
   <doc text sample text <x test< x words <lipsum> words words <x text< x some other text < doc (0.15467961)

query content:other
   <doc text sample text <x test< x words lipsum words words <x text< x some <other> text < doc (0.15467961)

query content:<x
   <doc text sample text <<x> test< x words lipsum words words <x text< x some other text < doc (0.21875)
   <doc text sample text <x test< x words lipsum words words <<x> text< x some other text < doc (0.21875)

query spanNear([content:lipsum, content:<x], 2, false)
   <doc text sample text <x test< x words <lipsum words words <x> text< x some other text < doc (0.19565594)

query spanNear([content:other, content:<x], 2, false)
    NO spans
...