Skip to content

Instantly share code, notes, and snippets.

@unclebean
Last active March 17, 2025 02:54
Show Gist options
  • Save unclebean/9a2ff81401c5dd268f50a609089775c6 to your computer and use it in GitHub Desktop.
Save unclebean/9a2ff81401c5dd268f50a609089775c6 to your computer and use it in GitHub Desktop.
solr
spring.data.solr.host=http://localhost:8983/solr
spring.data.solr.core=your_core_name
spring.data.solr.username=solr_user
spring.data.solr.password=solr_password
SolrClient solrClient = new HttpSolrClient.Builder("http://localhost:8983/solr/your_core").build();
SolrRequest request = new V2Request.Builder("/schema")
.withMethod(SolrRequest.METHOD.POST)
.withPayload("{\"add-field\": {\"name\":\"new_field\", \"type\":\"text_general\", \"stored\":true, \"indexed\":true}}")
.build();
solrClient.request(request);
solrClient.close();
import org.springframework.data.solr.repository.SolrCrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface SolrDocumentRepository extends SolrCrudRepository<SolrDocumentEntity, String> {
List<SolrDocumentEntity> findByTitleContaining(String title);
}
{
"add-field": [
{ "name": "title", "type": "text_general", "stored": true, "indexed": true },
{ "name": "description", "type": "text_general", "stored": true, "indexed": true },
{ "name": "price", "type": "pfloat", "stored": true, "indexed": true },
{ "name": "category", "type": "string", "stored": true, "indexed": true }
]
}
@Service
public class ReactiveSolrService {
@Autowired
private SolrClient solrClient;
public Flux<SolrDocument> queryWithFallback(String preFilter, Predicate<SolrDocument> postFilter, int batchSize) {
return querySolrWithPreFilter(preFilter, batchSize)
.onErrorResume(e -> {
if (isBooleanQueryLimitException(e)) {
// Switch to post-filter when pre-filter fails
return querySolrWithPostFilter(postFilter, batchSize);
}
return Flux.error(e);
});
}
private Flux<SolrDocument> querySolrWithPreFilter(String filter, int batchSize) {
return Flux.create(emitter -> {
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
boolean done = false;
try {
while (!done) {
SolrQuery query = new SolrQuery("*:*");
query.setFilterQueries(preFilter);
query.setRows(batchSize);
query.setSort("id", SolrQuery.ORDER.asc);
query.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
QueryResponse rsp = solrClient.query(query);
SolrDocumentList docs = rsp.getResults();
docsNotEmpty(docs).forEach(emitter::next);
String nextCursorMark = rsp.getNextCursorMark();
done = cursorMark.equals(nextCursorMark);
cursorMark = nextCursorMark;
}
emitter.complete();
} catch (Exception e) {
emitter.error(e);
}
});
}
private Flux<SolrDocument> querySolrWithPostFilter(Predicate<SolrDocument> postFilter, int batchSize) {
return Flux.create(emitter -> {
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
boolean done = false;
try {
while (!done) {
SolrQuery query = new SolrQuery("*:*");
query.setRows(batchSize);
query.setSort("id", SolrQuery.ORDER.asc);
query.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
QueryResponse rsp = solrClient.query(query);
String nextCursorMark = rsp.getNextCursorMark();
docsNotEmpty(rsp.getResults()).stream()
.filter(postFilter)
.forEach(emitter::next);
done = cursorMark.equals(nextCursorMark);
cursorMark = nextCursorMark;
}
emitter.complete();
} catch (Exception e) {
emitter.error(e);
}
});
}
private boolean isBooleanQueryLimitException(Throwable e) {
return e instanceof SolrException && ((SolrException)e).code() == SolrException.ErrorCode.BAD_REQUEST.code;
}
private SolrDocumentList docsNotEmpty(SolrDocumentList docs) {
return docs != null ? docs : new SolrDocumentList();
}
}
SolrQuery query = new SolrQuery();
query.setQuery("Spring Boot SolrJ"); // Main search query
query.set("qf", "title description"); // Search within multiple fields
// Enforce authorization condition: Only allow type "AA" or "BB"
query.setFilterQueries("type:(AA OR BB)");
// Execute query
QueryResponse response = solrClient.query(query);
SolrDocumentList results = response.getResults();
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
public class SolrCloudSearch {
public static void main(String[] args) throws Exception {
String zkHosts = "zookeeper1:2181,zookeeper2:2181,zookeeper3:2181"; // Zookeeper hosts
String collection = "your_collection_name";
try (SolrClient solrClient = new CloudHttp2SolrClient.Builder().withZkHost(zkHosts).build()) {
// Create a Solr query
SolrQuery query = new SolrQuery();
query.setQuery("name:Test");
query.setRows(10);
// Execute query
QueryResponse response = solrClient.query(collection, query);
SolrDocumentList documents = response.getResults();
// Print results
System.out.println("Found " + documents.getNumFound() + " documents:");
for (SolrDocument doc : documents) {
System.out.println("ID: " + doc.getFieldValue("id"));
System.out.println("Name: " + doc.getFieldValue("name"));
}
}
}
}
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.impl.HttpClientUtil;
import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SolrConfig {
@Value("${spring.data.solr.host}")
private String solrUrl;
@Value("${spring.data.solr.username}")
private String solrUsername;
@Value("${spring.data.solr.password}")
private String solrPassword;
@Bean
public HttpSolrClient solrClient() {
// Set up Basic Authentication
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(solrUsername, solrPassword));
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpSolrClient.Builder builder = new HttpSolrClient.Builder(solrUrl)
.withHttpClient(httpClient);
return builder.build();
}
}
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.apache.solr.common.SolrInputDocument;
public class SolrStandaloneClient {
public static void main(String[] args) throws Exception {
String solrUrl = "http://localhost:8983/solr/your_core_name";
String username = "your-username";
String password = "your-password";
// Set global authentication
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});
// Create Solr client
try (SolrClient solrClient = new Http2SolrClient.Builder(solrUrl).build()) {
System.out.println("Authenticated Solr client created successfully!");
}
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/solr")
public class SolrDocumentController {
@Autowired
private SolrDocumentService solrDocumentService;
@PostMapping("/add")
public String addDocument(@RequestBody SolrDocumentEntity document) {
solrDocumentService.saveDocument(document);
return "Document added successfully!";
}
@GetMapping("/search")
public List<SolrDocumentEntity> searchByTitle(@RequestParam String title) {
return solrDocumentService.searchByTitle(title);
}
@GetMapping("/{id}")
public Optional<SolrDocumentEntity> getById(@PathVariable String id) {
return solrDocumentService.findById(id);
}
@DeleteMapping("/{id}")
public String deleteById(@PathVariable String id) {
solrDocumentService.deleteById(id);
return "Document deleted successfully!";
}
@GetMapping("/advanced")
public Page<SolrDocumentEntity> advancedSearch(@RequestParam String query,
@RequestParam int page,
@RequestParam int size) {
return solrDocumentService.advancedSearch(query, PageRequest.of(page, size));
}
}
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.SolrDocument;
@SolrDocument(collection = "your_core_name")
public class SolrDocumentEntity {
@Id
@Field
private String id;
@Field("title")
private String title;
@Field("description")
private String description;
// Getters and Setters
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class SolrDocumentService {
@Autowired
private SolrDocumentRepository solrDocumentRepository;
@Autowired
private SolrTemplate solrTemplate;
public void saveDocument(SolrDocumentEntity document) {
solrDocumentRepository.save(document);
}
public List<SolrDocumentEntity> searchByTitle(String title) {
return solrDocumentRepository.findByTitleContaining(title);
}
public Optional<SolrDocumentEntity> findById(String id) {
return solrDocumentRepository.findById(id);
}
public void deleteById(String id) {
solrDocumentRepository.deleteById(id);
}
public Page<SolrDocumentEntity> advancedSearch(String query, Pageable pageable) {
SimpleQuery simpleQuery = new SimpleQuery(query).setPageRequest(pageable);
return solrTemplate.queryForPage("your_core_name", simpleQuery, SolrDocumentEntity.class);
}
}
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.V2Request;
import org.apache.solr.client.solrj.SolrRequest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@Service
public class SolrSchemaService {
private static final String SOLR_URL = "http://localhost:8983/solr/your_core";
private final SolrClient solrClient;
public SolrSchemaService() {
this.solrClient = new HttpSolrClient.Builder(SOLR_URL).build();
}
public void createIndexFieldsFromJson() throws Exception {
// Read JSON file from classpath
String jsonPayload = readJsonFile("schema-fields.json");
// Use SolrJ V2 API to send the JSON to Solr
SolrRequest request = new V2Request.Builder("/schema")
.withMethod(SolrRequest.METHOD.POST)
.withPayload(jsonPayload)
.build();
// Execute request
solrClient.request(request);
System.out.println("Index fields created successfully!");
}
private String readJsonFile(String fileName) throws IOException {
Path path = new ClassPathResource(fileName).getFile().toPath();
return Files.readString(path);
}
}
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SolrSearchService {
@Autowired
private SolrClient solrClient;
public SolrDocumentList searchDocuments(String queryStr) {
try {
SolrQuery query = new SolrQuery();
query.setQuery(queryStr);
QueryResponse response = solrClient.query("your_core_name", query);
return response.getResults();
} catch (Exception e) {
throw new RuntimeException("Solr search failed", e);
}
}
}
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SolrService {
private final SolrClient solrClient;
@Autowired
public SolrService(SolrClient solrClient) {
this.solrClient = solrClient;
}
public void addDocument(SolrInputDocument document) throws Exception {
solrClient.add(document);
solrClient.commit();
}
public QueryResponse query(String queryString) throws Exception {
SolrQuery query = new SolrQuery();
query.setQuery(queryString);
return solrClient.query(query);
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>11.0.15</version> <!-- Ensure this matches Solr 9.2 -->
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>11.0.15</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>9.2.0</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>9.4.52.v20230823</version> <!-- Use a compatible version -->
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>9.4.52.v20230823</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.52.v20230823</version>
</dependency>
--------------
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>10.0.13</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>10.0.13</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
<version>10.0.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>10.0.13</version>
</dependency>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment