1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.score;
17
18 import java.util.Arrays;
19 import java.util.Map;
20 import java.util.function.Function;
21
22 import org.apache.logging.log4j.LogManager;
23 import org.apache.logging.log4j.Logger;
24 import org.codelibs.core.lang.StringUtil;
25 import org.codelibs.fess.mylasta.direction.FessConfig;
26 import org.codelibs.fess.opensearch.client.SearchEngineClient;
27 import org.codelibs.fess.util.ComponentUtil;
28 import org.opensearch.action.bulk.BulkRequestBuilder;
29 import org.opensearch.action.bulk.BulkResponse;
30 import org.opensearch.action.search.SearchResponse;
31 import org.opensearch.action.update.UpdateRequestBuilder;
32 import org.opensearch.index.query.QueryBuilders;
33 import org.opensearch.script.Script;
34 import org.opensearch.script.ScriptType;
35 import org.opensearch.search.SearchHit;
36
37
38
39
40 public abstract class ScoreBooster {
41
42
43
44 public ScoreBooster() {
45 super();
46 }
47
48 private static final Logger logger = LogManager.getLogger(ScoreBooster.class);
49
50
51
52
53 protected BulkRequestBuilder bulkRequestBuilder = null;
54
55
56
57
58 protected int priority = 1;
59
60
61
62
63 protected String requestTimeout = "1m";
64
65
66
67
68 protected int requestCacheSize = 1000;
69
70
71
72
73 protected String scriptLang = "painless";
74
75
76
77
78 protected String scriptCode = null;
79
80
81
82
83 protected Function<Map<String, Object>, String[]> idFinder = params -> {
84 final FessConfig fessConfig = ComponentUtil.getFessConfig();
85 final SearchEngineClient client = ComponentUtil.getSearchEngineClient();
86 final String index = fessConfig.getIndexDocumentUpdateIndex();
87 final Object url = params.get("url");
88 if (url == null) {
89 return StringUtil.EMPTY_STRINGS;
90 }
91 final SearchResponse response = client.prepareSearch(index)
92 .setQuery(QueryBuilders.termQuery(fessConfig.getIndexFieldUrl(), url))
93 .setFetchSource(false)
94 .setSize(fessConfig.getPageScoreBoosterMaxFetchSizeAsInteger())
95 .execute()
96 .actionGet(requestTimeout);
97 return Arrays.stream(response.getHits().getHits()).map(SearchHit::getId).toArray(n -> new String[n]);
98 };
99
100
101
102
103 protected Function<Map<String, Object>, Long> requestHandler = params -> {
104 final FessConfig fessConfig = ComponentUtil.getFessConfig();
105 final String[] ids = idFinder.apply(params);
106 if (ids.length == 0) {
107 return 0L;
108 }
109 final SearchEngineClient client = ComponentUtil.getSearchEngineClient();
110 if (bulkRequestBuilder == null) {
111 bulkRequestBuilder = client.prepareBulk();
112 }
113 final String index = fessConfig.getIndexDocumentUpdateIndex();
114 for (final String id : ids) {
115 bulkRequestBuilder.add(client.prepareUpdate()
116 .setIndex(index)
117 .setId(id)
118 .setScript(new Script(ScriptType.INLINE, scriptLang, scriptCode, params)));
119 }
120 if (bulkRequestBuilder.numberOfActions() > requestCacheSize) {
121 flush();
122 }
123 return (long) ids.length;
124 };
125
126
127
128
129
130 public abstract long process();
131
132
133
134
135 protected void enable() {
136 final ScoreUpdater scoreUpdater = ComponentUtil.getComponent("scoreUpdater");
137 scoreUpdater.addScoreBooster(this);
138 }
139
140
141
142
143
144
145 protected long updateScore(final Map<String, Object> params) {
146 return requestHandler.apply(params);
147 }
148
149
150
151
152
153 protected UpdateRequestBuilder createUpdateRequestBuilder() {
154 final FessConfig fessConfig = ComponentUtil.getFessConfig();
155 return ComponentUtil.getSearchEngineClient().prepareUpdate().setIndex(fessConfig.getIndexDocumentSearchIndex());
156 }
157
158
159
160
161 protected void flush() {
162 if (bulkRequestBuilder != null) {
163 final BulkResponse response = bulkRequestBuilder.execute().actionGet(requestTimeout);
164 if (response.hasFailures()) {
165 logger.warn("Failed to update scores: {}", response.buildFailureMessage());
166 }
167 bulkRequestBuilder = null;
168 }
169 }
170
171
172
173
174
175 public int getPriority() {
176 return priority;
177 }
178
179
180
181
182
183 public void setPriority(final int priority) {
184 this.priority = priority;
185 }
186
187
188
189
190
191 public void setRequestTimeout(final String bulkRequestTimeout) {
192 requestTimeout = bulkRequestTimeout;
193 }
194
195
196
197
198
199 public void setRequestCacheSize(final int requestCacheSize) {
200 this.requestCacheSize = requestCacheSize;
201 }
202
203
204
205
206
207 public void setScriptLang(final String scriptLang) {
208 this.scriptLang = scriptLang;
209 }
210
211
212
213
214
215 public void setScriptCode(final String scriptCode) {
216 this.scriptCode = scriptCode;
217 }
218 }