mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-07-19 19:16:11 +00:00
feat: 新增贴文reindex
This commit is contained in:
@@ -18,6 +18,8 @@ public class OpenSearchProperties {
|
|||||||
private String indexPrefix = "openisle";
|
private String indexPrefix = "openisle";
|
||||||
private boolean initialize = true;
|
private boolean initialize = true;
|
||||||
private int highlightFragmentSize = 200;
|
private int highlightFragmentSize = 200;
|
||||||
|
private boolean reindexOnStartup = false;
|
||||||
|
private int reindexBatchSize = 500;
|
||||||
|
|
||||||
private Indices indices = new Indices();
|
private Indices indices = new Indices();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.openisle.search;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SearchReindexInitializer implements CommandLineRunner {
|
||||||
|
|
||||||
|
private final OpenSearchProperties properties;
|
||||||
|
private final SearchReindexService searchReindexService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(String... args) {
|
||||||
|
if (!properties.isEnabled()) {
|
||||||
|
log.info("Search indexing disabled, skipping startup reindex.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!properties.isReindexOnStartup()) {
|
||||||
|
log.debug("Startup reindex disabled by configuration.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchReindexService.reindexAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.openisle.search;
|
||||||
|
|
||||||
|
import com.openisle.model.Post;
|
||||||
|
import com.openisle.model.PostStatus;
|
||||||
|
import com.openisle.model.Tag;
|
||||||
|
import com.openisle.repository.CategoryRepository;
|
||||||
|
import com.openisle.repository.CommentRepository;
|
||||||
|
import com.openisle.repository.PostRepository;
|
||||||
|
import com.openisle.repository.TagRepository;
|
||||||
|
import com.openisle.repository.UserRepository;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SearchReindexService {
|
||||||
|
|
||||||
|
private final SearchIndexer searchIndexer;
|
||||||
|
private final OpenSearchProperties properties;
|
||||||
|
private final PostRepository postRepository;
|
||||||
|
private final CommentRepository commentRepository;
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
private final CategoryRepository categoryRepository;
|
||||||
|
private final TagRepository tagRepository;
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public void reindexAll() {
|
||||||
|
if (!properties.isEnabled()) {
|
||||||
|
log.info("Search indexing is disabled, skipping reindex operation.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Starting full search reindex operation.");
|
||||||
|
|
||||||
|
reindex(properties.postsIndex(), postRepository::findAll, (Post post) ->
|
||||||
|
post.getStatus() == PostStatus.PUBLISHED ? SearchDocumentFactory.fromPost(post) : null
|
||||||
|
);
|
||||||
|
|
||||||
|
reindex(
|
||||||
|
properties.commentsIndex(),
|
||||||
|
commentRepository::findAll,
|
||||||
|
SearchDocumentFactory::fromComment
|
||||||
|
);
|
||||||
|
|
||||||
|
reindex(properties.usersIndex(), userRepository::findAll, SearchDocumentFactory::fromUser);
|
||||||
|
|
||||||
|
reindex(
|
||||||
|
properties.categoriesIndex(),
|
||||||
|
categoryRepository::findAll,
|
||||||
|
SearchDocumentFactory::fromCategory
|
||||||
|
);
|
||||||
|
|
||||||
|
reindex(properties.tagsIndex(), tagRepository::findAll, (Tag tag) ->
|
||||||
|
tag.isApproved() ? SearchDocumentFactory.fromTag(tag) : null
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("Completed full search reindex operation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void reindex(
|
||||||
|
String index,
|
||||||
|
Function<Pageable, Page<T>> pageSupplier,
|
||||||
|
Function<T, SearchDocument> mapper
|
||||||
|
) {
|
||||||
|
int batchSize = Math.max(1, properties.getReindexBatchSize());
|
||||||
|
int pageNumber = 0;
|
||||||
|
|
||||||
|
Page<T> page;
|
||||||
|
do {
|
||||||
|
Pageable pageable = PageRequest.of(pageNumber, batchSize);
|
||||||
|
page = pageSupplier.apply(pageable);
|
||||||
|
if (page.isEmpty() && pageNumber == 0) {
|
||||||
|
log.info("No entities found for index {}.", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Reindexing {} entities for index {}.", page.getTotalElements(), index);
|
||||||
|
for (T entity : page) {
|
||||||
|
SearchDocument document = mapper.apply(entity);
|
||||||
|
if (Objects.nonNull(document)) {
|
||||||
|
searchIndexer.indexDocument(index, document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageNumber++;
|
||||||
|
} while (page.hasNext());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,6 +54,8 @@ app.search.username=${SEARCH_USERNAME:}
|
|||||||
app.search.password=${SEARCH_PASSWORD:}
|
app.search.password=${SEARCH_PASSWORD:}
|
||||||
app.search.index-prefix=${SEARCH_INDEX_PREFIX:openisle}
|
app.search.index-prefix=${SEARCH_INDEX_PREFIX:openisle}
|
||||||
app.search.highlight-fragment-size=${SEARCH_HIGHLIGHT_FRAGMENT_SIZE:${SNIPPET_LENGTH:200}}
|
app.search.highlight-fragment-size=${SEARCH_HIGHLIGHT_FRAGMENT_SIZE:${SNIPPET_LENGTH:200}}
|
||||||
|
app.search.reindex-on-startup=${SEARCH_REINDEX_ON_STARTUP:true}
|
||||||
|
app.search.reindex-batch-size=${SEARCH_REINDEX_BATCH_SIZE:500}
|
||||||
|
|
||||||
# Captcha configuration
|
# Captcha configuration
|
||||||
app.captcha.enabled=${CAPTCHA_ENABLED:false}
|
app.captcha.enabled=${CAPTCHA_ENABLED:false}
|
||||||
|
|||||||
Reference in New Issue
Block a user