Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
bba4191
integrate lucene-monitor into solr
kotman12 Mar 30, 2024
fe3b413
move MonitorDataValues and check in license
kotman12 Apr 1, 2024
0989f1c
update versions.lock
kotman12 Apr 1, 2024
62ddcbc
add package-info to monitor packages
kotman12 Apr 1, 2024
33eccf7
extract helper method
kotman12 Apr 1, 2024
fa7fb40
apply errorprone suggestions
kotman12 Apr 3, 2024
11a1138
implement highlight matches
kotman12 Apr 4, 2024
7526b2f
AggregatingMatcher -> MatchesAggregator
kotman12 Apr 4, 2024
6ac7a5e
make monitor query cache optional
kotman12 Apr 4, 2024
2362ce7
move manySegmentsTest to ParallelMonitorSolrQueryTest
kotman12 Apr 4, 2024
e5a1382
call CandidateMatcher directly
kotman12 Apr 5, 2024
b7b58b3
remove doc forwarding callback
kotman12 Apr 6, 2024
ce40d60
instantiate decoder in outer loop
kotman12 Apr 9, 2024
a201676
ignore score for relevant match types
kotman12 Apr 12, 2024
60b0eb5
read MAX_SIZE_PARAM for maxSize
kotman12 Apr 12, 2024
fd04c4e
don't drop cause
kotman12 Apr 12, 2024
32cb6f6
remove superstitious delete calls
kotman12 Apr 12, 2024
b6d369b
add testDeleteByQueryId
kotman12 Apr 12, 2024
0ab5a6b
enable setting maxRamMB for monitor cache
kotman12 Apr 13, 2024
0b0120e
hardcoding luceneMatchVersion is bad
kotman12 Apr 15, 2024
24c1bf5
add multi-pass presearcher and optional field aliasing
kotman12 Apr 19, 2024
ee2992d
more accurate error
kotman12 Apr 19, 2024
6815ea1
redundant override
kotman12 Apr 19, 2024
995cfa2
wrap reserved field with _ and remove override behavior
kotman12 Apr 24, 2024
a2419ff
validate MonitorFields.RESERVED_MONITOR_FIELDS in schema
kotman12 Apr 24, 2024
0fde7ef
stricter validations of required fields
kotman12 Apr 27, 2024
5968754
narrow scope of __anytokenfield validation
kotman12 Apr 27, 2024
bb11982
getBool with default
kotman12 May 3, 2024
eba6e2d
initialize Presearcher in ReverseSearchComponent + add ReverseSearchH…
kotman12 May 4, 2024
d3ccf0c
remove unused constant
kotman12 May 4, 2024
e12ec6f
make SolrMonitorCache name optionally configurable
cpoerschke May 10, 2024
6d4986c
[exploratory] turn MonitorConstants.QUERY_DECOMPOSER into ReverseSear…
cpoerschke May 10, 2024
3aae9f0
remove REVERSE_SEARCH_PARAM_NAME flag in favor of dedicated path
kotman12 May 10, 2024
0915ce1
move getComponent from QCEVisitor to SolrMonitorQueryDecoder as sugge…
cpoerschke May 14, 2024
e6e25a5
avoid queryDecoder.getComponent(queryDecoder.decode(...), ...) usage …
cpoerschke May 14, 2024
8bb7151
Merge remote-tracking branch 'github_kotman12/solr-monitor' into solr…
cpoerschke May 14, 2024
e1365ad
remove now no-longer-used MonitorConstants.QUERY_DECOMPOSER
cpoerschke May 15, 2024
5b37a6a
coexistWithRegularDocumentsTest with multiple update chains
kotman12 Jun 4, 2024
e4af381
remove payload and additional field support
kotman12 Jun 4, 2024
7be05a3
validate fields in MonitorUpdateRequestProcessor
kotman12 Jun 4, 2024
f2d47be
start MonitorSolrQueryTest.validateDocList
cpoerschke Jun 14, 2024
d359f80
defer parallel matching from initial integration
cpoerschke Jun 17, 2024
4af2c57
move manySegments and multiPass to SingleCoreMonitorSolrTest
kotman12 Jun 22, 2024
ef8dafd
Merge remote-tracking branch 'github_kotman12/solr-monitor' into solr…
cpoerschke Jun 24, 2024
f3b33b1
Merge remote-tracking branch 'github_kotman12/solr-monitor' into solr…
cpoerschke Jun 24, 2024
7feb415
restore ParallelMonitorSolrQueryTest.java
cpoerschke Jun 24, 2024
a3c4d36
Merge pull request #2 from cpoerschke/solr-monitor-cpoerschke-5
kotman12 Jun 24, 2024
ebc4fb9
Merge pull request #1 from cpoerschke/solr-monitor-cpoerschke-4
kotman12 Jun 24, 2024
e33e8ae
./gradlew tidy
cpoerschke Jun 24, 2024
05438f4
defer monitorMatchType support (always use simple matching)
cpoerschke Jun 24, 2024
483e46f
always use ConstantScoreQuery
kotman12 Jun 25, 2024
9ed6b48
Merge remote-tracking branch 'origin/main' into solr-monitor
cpoerschke Jul 1, 2024
28bf264
remove MonitorFields.ANYTOKEN_FIELD in favour of TermFilteredPresearc…
cpoerschke Jul 1, 2024
908f462
Merge pull request #3 from cpoerschke/solr-monitor-cpoerschke-6
kotman12 Nov 8, 2024
13dffda
add back inadvertently removed import
cpoerschke Nov 8, 2024
cbf45de
remove stand-alone monitor API
kotman12 Nov 12, 2024
a3fc3d5
Merge branch 'solr-monitor' of https://github.com/kotman12/solr into …
kotman12 Nov 12, 2024
a24d66a
fix tests
kotman12 Nov 12, 2024
44eea79
avoid (minimise) solr/core changes
cpoerschke Nov 13, 2024
bf0daf7
tentative: no need to configure the query component
cpoerschke Nov 13, 2024
3e7a53c
subjective: remove SolrMatcherSinkFactory now that there's only one S…
cpoerschke Nov 13, 2024
113ca8f
some ReverseSearchComponent.prepare reordering and edits to aid code …
cpoerschke Nov 13, 2024
102cdf0
remove MatchesAggregator.java
kotman12 Nov 18, 2024
5850f8c
Merge branch 'main' of https://github.com/kotman12/solr into solr-mon…
kotman12 Nov 23, 2024
acd144f
Merge branch 'main' of https://github.com/kotman12/solr into solr-mon…
kotman12 Nov 23, 2024
3795013
update build files
kotman12 Nov 23, 2024
6989703
remove MonitorConstants
kotman12 Nov 23, 2024
1e62be2
debug component refactor
kotman12 Nov 24, 2024
f840f97
ReverseSearchQuery proof-of-concept
kotman12 Nov 25, 2024
4cc04c4
handle null scorer
kotman12 Nov 25, 2024
e68c329
wire lucene-monitor metadata to solr response
kotman12 Nov 25, 2024
c1d3f72
simplify interface and implement toString
kotman12 Nov 29, 2024
33e7400
Merge pull request #6 from kotman12/solr-monitor-rsq
kotman12 Dec 1, 2024
42e5f44
clean up
kotman12 Dec 2, 2024
882cda9
pull latest CandidateMatcher
kotman12 Dec 2, 2024
7c80dae
monitor -> saved-search
kotman12 Dec 2, 2024
50ec78c
Merge pull request #7 from kotman12/solr-monitor-test
kotman12 Dec 3, 2024
d869b33
monitor -> savedsearch package
kotman12 Dec 4, 2024
4665004
make SolrResourceLoader aware of savedsearch paths
kotman12 Dec 5, 2024
9a45f17
fix analyzeDependency error
kotman12 Dec 5, 2024
613b6cd
rename stuff to SavedSearch*
kotman12 Dec 5, 2024
2ad0db2
consolidate lucene-monitor visitors
kotman12 Dec 10, 2024
858d6b2
+mixed select -reader closing bug -QueryIndex.FIELDS reference
kotman12 Jun 24, 2025
9b48a7f
add test to detect AlreadyClosedException
kotman12 Jun 26, 2025
42fa246
initialize cache on start-up
kotman12 Jun 26, 2025
ed27b22
remove cache_id and QCEVisitor
kotman12 Jun 27, 2025
36eb409
move VersionedQueryCacheEntry.java to SavedSearchCache
kotman12 Jun 27, 2025
180d821
move VersionedQueryCacheEntry.java to SavedSearchCache
kotman12 Jun 27, 2025
9d3c63d
move regenerator into DefaultSavedSearchCache
kotman12 Jun 27, 2025
4d9542b
small refactor
kotman12 Jun 28, 2025
3a3bdc8
stop stashing solrMatcherSink in context for no reason
kotman12 Jun 28, 2025
f6589a7
don't skip docs during cache regeneration
kotman12 Aug 23, 2025
3ce9b6e
Merge branch 'main' of https://github.com/kotman12/solr into solr-mon…
kotman12 Aug 23, 2025
8865e0b
Merge branch 'main' of https://github.com/kotman12/solr into solr-mon…
kotman12 Aug 23, 2025
0fc2b1f
merge main + minor cache tweak
kotman12 Sep 4, 2025
cfa3426
update lucene-monitor license
kotman12 Sep 8, 2025
1fdab75
Merge branch 'main' of https://github.com/kotman12/solr into solr-mon…
kotman12 Sep 8, 2025
35b2a40
remove referential equality
kotman12 Sep 9, 2025
c6e207e
keep track of max version per segment
kotman12 Sep 9, 2025
58caac9
don't reject unsupported fields because it breaks tlog replay
kotman12 Sep 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ apache-lucene-grouping = { module = "org.apache.lucene:lucene-grouping", version
apache-lucene-highlighter = { module = "org.apache.lucene:lucene-highlighter", version.ref = "apache-lucene" }
apache-lucene-join = { module = "org.apache.lucene:lucene-join", version.ref = "apache-lucene" }
apache-lucene-misc = { module = "org.apache.lucene:lucene-misc", version.ref = "apache-lucene" }
apache-lucene-monitor = { module = "org.apache.lucene:lucene-monitor", version.ref = "apache-lucene" }
apache-lucene-queries = { module = "org.apache.lucene:lucene-queries", version.ref = "apache-lucene" }
apache-lucene-queryparser = { module = "org.apache.lucene:lucene-queryparser", version.ref = "apache-lucene" }
apache-lucene-sandbox = { module = "org.apache.lucene:lucene-sandbox", version.ref = "apache-lucene" }
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ include "solr:modules:ltr"
include "solr:modules:s3-repository"
include "solr:modules:scripting"
include "solr:modules:sql"
include "solr:modules:saved-search"
include "solr:webapp"
include "solr:benchmark"
include "solr:test-framework"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ public class SolrResourceLoader
"security.cert.",
"handler.sql.",
"crossdc.handler.",
"crossdc.update.processor."
"crossdc.update.processor.",
"savedsearch.",
"savedsearch.cache.",
"savedsearch.search.",
"savedsearch.update."
};
private static final Charset UTF_8 = StandardCharsets.UTF_8;
public static final String SOLR_RESOURCELOADING_RESTRICTED_ENABLED_PARAM =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ public void process(ResponseBuilder rb) throws IOException {
info.add("facet-debug", fdebug.getFacetDebugInfo());
}

CustomDebugInfoSources customDebugInfoSources =
(CustomDebugInfoSources) rb.req.getContext().get(CustomDebugInfoSources.KEY);
if (customDebugInfoSources != null) {
for (var customDebugInfoSource : customDebugInfoSources.list) {
info.add(customDebugInfoSource.name, customDebugInfoSource.values);
}
}

if (rb.req.getJSON() != null) {
info.add(JSON, rb.req.getJSON());
}
Expand All @@ -140,6 +148,28 @@ public void process(ResponseBuilder rb) throws IOException {
}
}

public static class CustomDebugInfoSources {

public static final String KEY = "CustomDebugInfoSources";

private final List<CustomDebugInfoSource> list = new ArrayList<>();

public void add(CustomDebugInfoSource source) {
list.add(source);
}
}

public static class CustomDebugInfoSource {

private final String name;
private final SimpleOrderedMap<Object> values;

public CustomDebugInfoSource(String name, SimpleOrderedMap<Object> values) {
this.name = name;
this.values = values;
}
}

private void doDebugTrack(ResponseBuilder rb) {
final String rid = rb.req.getParams().get(CommonParams.REQUEST_ID);
rb.addDebug(rid, "track", CommonParams.REQUEST_ID); // to see it in the response
Expand Down
1 change: 1 addition & 0 deletions solr/licenses/lucene-monitor-10.2.1.jar.sha1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
28f441a84d0b5e2ae11e1585e03144ccd7ad1f0c
34 changes: 34 additions & 0 deletions solr/modules/saved-search/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.
*/

apply plugin: 'java-library'

description = 'Apache Solr Monitor'

dependencies {

implementation project(":solr:core")
implementation project(":solr:solrj")
implementation libs.apache.lucene.core
implementation libs.apache.lucene.monitor
implementation libs.benmanes.caffeine
implementation libs.dropwizard.metrics.core
testImplementation project(':solr:test-framework')
testImplementation libs.junit.junit
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
*
* *
* * * 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.List;
import java.util.function.BiPredicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.util.BytesRef;

public class Visitors {

public static class DocumentBatchVisitor implements AutoCloseable, Supplier<LeafReader> {

private final DocumentBatch batch;
private final List<Document> docs;

private DocumentBatchVisitor(DocumentBatch batch, List<Document> docs) {
this.batch = batch;
this.docs = docs;
}

public static DocumentBatchVisitor of(Analyzer analyzer, List<Document> docs) {
return new DocumentBatchVisitor(
DocumentBatch.of(analyzer, docs.toArray(new Document[0])), docs);
}

@Override
public void close() throws IOException {
batch.close();
}

@Override
public LeafReader get() {
return batch.get();
}

public int size() {
return docs.size();
}

@Override
public String toString() {
return docs.stream().map(Document::toString).collect(Collectors.joining(" "));
}
}

public static class QueryTermFilterVisitor implements BiPredicate<String, BytesRef> {

private final QueryIndex.QueryTermFilter queryTermFilter;

public QueryTermFilterVisitor(IndexReader reader) throws IOException {
this.queryTermFilter = new QueryIndex.QueryTermFilter(reader);
}

@Override
public boolean test(String field, BytesRef bytesRef) {
return queryTermFilter.test(field, bytesRef);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
*
* * 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.solr.savedsearch;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiPredicate;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.monitor.CustomQueryHandler;
import org.apache.lucene.monitor.MultipassTermFilteredPresearcher;
import org.apache.lucene.monitor.Presearcher;
import org.apache.lucene.monitor.TermFilteredPresearcher;
import org.apache.lucene.monitor.TermWeightor;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;

/**
* The motivation behind this is to map each document field to its corresponding, presearcher-owned
* equivalent. By prefixing we ensure "presearcher fields" don't inadvertently affect the scores of
* "real" document fields. Another issue is that the presearcher can dynamically create field
* configurations for a given field name that might not be compatible with the pre-existing schema
* definition, see {\@link
* org.apache.solr.savedsearch.SingleCoreSavedSearchTest#coexistWithRegularDocumentsTest}. In the
* case of {@link org.apache.lucene.monitor.MultipassTermFilteredPresearcher#field(String, int)},
* the presearcher is capable of creating new fields by adding an ordinal suffix to an existing
* field name. This could also clash with user-defined name patterns, hence the existence of this
* class, which allows users to alias presearcher fields as they see fit.
*/
public class AliasingPresearcher extends Presearcher {

private final Presearcher aliasingPresearcher;
private final String prefix;

AliasingPresearcher(Presearcher aliasingPresearcher, String prefix) {
this.aliasingPresearcher = aliasingPresearcher;
this.prefix = prefix;
}

@Override
public Query buildQuery(LeafReader reader, BiPredicate<String, BytesRef> termAcceptor) {
BiPredicate<String, BytesRef> aliasingTermAcceptor =
(fieldName, term) -> termAcceptor.test(prefix + fieldName, term);
return aliasingPresearcher.buildQuery(reader, aliasingTermAcceptor);
}

@Override
public Document indexQuery(Query query, Map<String, String> metadata) {
var document = aliasingPresearcher.indexQuery(query, metadata);
return alias(document);
}

public String getPrefix() {
return prefix;
}

private Document alias(Document in) {
Document out = new Document();
for (var field : in) {
if (!TermFilteredPresearcher.ANYTOKEN_FIELD.equals(field.name())
&& field instanceof Field
&& ((Field) field).tokenStreamValue() != null) {
out.add(
new Field(
prefix + field.name(), ((Field) field).tokenStreamValue(), field.fieldType()));
} else {
out.add(field);
}
}
return out;
}

public static class MultiPassTermFiltered extends MultipassTermFilteredPresearcher {

private final String prefix;

private MultiPassTermFiltered(
int passes,
float minWeight,
TermWeightor weightor,
List<CustomQueryHandler> queryHandlers,
Set<String> filterFields,
String prefix) {
super(passes, minWeight, weightor, queryHandlers, filterFields);
this.prefix = prefix;
}

@Override
protected DocumentQueryBuilder getQueryBuilder() {
return new TermFiltered.AliasingDocumentQueryBuilder(super.getQueryBuilder(), prefix);
}

public static AliasingPresearcher build(
int passes,
float minWeight,
TermWeightor weightor,
List<CustomQueryHandler> queryHandlers,
Set<String> filterFields,
String prefix) {
return new AliasingPresearcher(
new MultiPassTermFiltered(
passes, minWeight, weightor, queryHandlers, filterFields, prefix),
prefix);
}
}

public static class TermFiltered extends TermFilteredPresearcher {

private final String prefix;

TermFiltered(
TermWeightor weightor,
List<CustomQueryHandler> customQueryHandlers,
Set<String> filterFields,
String prefix) {
super(weightor, customQueryHandlers, filterFields);
this.prefix = prefix;
}

public static AliasingPresearcher build(
TermWeightor weightor,
List<CustomQueryHandler> queryHandlers,
Set<String> filterFields,
String prefix) {
return new AliasingPresearcher(
new TermFiltered(weightor, queryHandlers, filterFields, prefix), prefix);
}

@Override
protected DocumentQueryBuilder getQueryBuilder() {
return new AliasingDocumentQueryBuilder(super.getQueryBuilder(), prefix);
}

static class AliasingDocumentQueryBuilder implements DocumentQueryBuilder {

private final DocumentQueryBuilder documentQueryBuilder;
private final String prefix;

public AliasingDocumentQueryBuilder(
DocumentQueryBuilder documentQueryBuilder, String prefix) {
this.documentQueryBuilder = documentQueryBuilder;
this.prefix = prefix;
}

@Override
public void addTerm(String field, BytesRef term) throws IOException {
documentQueryBuilder.addTerm(prefix + field, term);
}

@Override
public Query build() {
return documentQueryBuilder.build();
}
}
}
}
Loading