All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.lucene.monitor.HighlightsMatch Maven / Gradle / Ivy

There is a newer version: 9.11.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.lucene.monitor;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.Matches;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;

/**
 * QueryMatch object that contains the hit positions of a matching Query
 *
 * 

If the Query does not support interval iteration (eg, if it gets re-written to a Filter), then * no hits will be reported, but an IntervalsQueryMatch will still be returned from an * IntervalsMatcher to indicate a match. */ public class HighlightsMatch extends QueryMatch { public static final MatcherFactory MATCHER = searcher -> new CandidateMatcher(searcher) { @Override protected void matchQuery( String queryId, Query matchQuery, Map metadata) throws IOException { Weight w = searcher.createWeight( searcher.rewrite(matchQuery), ScoreMode.COMPLETE_NO_SCORES, 1); for (LeafReaderContext ctx : searcher.getIndexReader().leaves()) { for (int i = 0; i < ctx.reader().maxDoc(); i++) { Matches matches = w.matches(ctx, i); if (matches != null) { addMatch(buildMatch(matches, queryId), i); } } } } @Override public HighlightsMatch resolve(HighlightsMatch match1, HighlightsMatch match2) { return HighlightsMatch.merge(match1.getQueryId(), match1, match2); } private HighlightsMatch buildMatch(Matches matches, String queryId) throws IOException { HighlightsMatch m = new HighlightsMatch(queryId); for (String field : matches) { MatchesIterator mi = matches.getMatches(field); while (mi.next()) { MatchesIterator sub = mi.getSubMatches(); if (sub != null) { while (sub.next()) { m.addHit( field, sub.startPosition(), sub.endPosition(), sub.startOffset(), sub.endOffset()); } } else { m.addHit( field, mi.startPosition(), mi.endPosition(), mi.startOffset(), mi.endOffset()); } } } return m; } }; private final Map> hits; HighlightsMatch(String queryId) { super(queryId); this.hits = new TreeMap<>(); } /** * @return a map of hits per field */ public Map> getHits() { return Collections.unmodifiableMap(this.hits); } /** * @return the fields in which matches have been found */ public Set getFields() { return Collections.unmodifiableSet(hits.keySet()); } /** * Get the hits for a specific field * * @param field the field * @return the Hits found in this field */ public Collection getHits(String field) { Collection found = hits.get(field); if (found != null) return Collections.unmodifiableCollection(found); return Collections.emptyList(); } /** * @return the total number of hits for the query */ public int getHitCount() { int c = 0; for (Set fieldhits : hits.values()) { c += fieldhits.size(); } return c; } static HighlightsMatch merge(String queryId, HighlightsMatch... matches) { HighlightsMatch newMatch = new HighlightsMatch(queryId); for (HighlightsMatch match : matches) { for (String field : match.getFields()) { Set hitSet = newMatch.hits.computeIfAbsent(field, f -> new TreeSet<>()); hitSet.addAll(match.getHits(field)); } } return newMatch; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof HighlightsMatch)) return false; if (!super.equals(o)) return false; HighlightsMatch that = (HighlightsMatch) o; if (hits != null ? !hits.equals(that.hits) : that.hits != null) return false; return true; } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (hits != null ? hits.hashCode() : 0); return result; } @Override public String toString() { return super.toString() + "{hits=" + hits + "}"; } void addHit(String field, int startPos, int endPos, int startOffset, int endOffset) { Set hitSet = hits.computeIfAbsent(field, f -> new TreeSet<>()); hitSet.add(new Hit(startPos, startOffset, endPos, endOffset)); } /** Represents an individual hit */ public static class Hit implements Comparable { /** The start position */ public final int startPosition; /** The start offset */ public final int startOffset; /** The end positions */ public final int endPosition; /** The end offset */ public final int endOffset; public Hit(int startPosition, int startOffset, int endPosition, int endOffset) { this.startPosition = startPosition; this.startOffset = startOffset; this.endPosition = endPosition; this.endOffset = endOffset; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Hit)) return false; Hit other = (Hit) obj; return this.startOffset == other.startOffset && this.endOffset == other.endOffset && this.startPosition == other.startPosition && this.endPosition == other.endPosition; } @Override public int hashCode() { int result = startPosition; result = 31 * result + startOffset; result = 31 * result + endPosition; result = 31 * result + endOffset; return result; } @Override public String toString() { return String.format( Locale.ROOT, "%d(%d)->%d(%d)", startPosition, startOffset, endPosition, endOffset); } @Override public int compareTo(Hit other) { if (this.startPosition != other.startPosition) return Integer.compare(this.startPosition, other.startPosition); return Integer.compare(this.endPosition, other.endPosition); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy