Artikelverzeichnis
-
- Such-/Filterfunktion
- Andere Eigenschaften
-
- 1. Markieren Sie Suchergebnisse
- 2. Geolokalisierungssuche
- 3. Benutzerdefinierter Analysator
- 4. Benutzerdefinierte Abfrage
- 5. Verwenden von Spring's Page and Sort
- 6. Skriptabfrage
- 7. Multi-Index-Abfrage
- 8. Mehrsprachige Unterstützung
- 9. Verbindungspoolverwaltung
- 10. Versionskontrolle des Dokuments
- 11. Suchvorschläge
- Großer Koffer für eine E-Commerce-Plattform
Such-/Filterfunktion
1. Volltextsuche
Spring Data Elasticsearch unterstützt die Volltextsuchfunktion, die das Auffinden von Schlüsselwörtern in Textdaten sehr einfach macht. Wir können die Annotation @Field
verwenden, um das Textfeld anzugeben, und die Volltextsuchabfrage verwenden, um den Suchvorgang durchzuführen.
@Field(type = FieldType.Text, analyzer = "standard")
private String title;
2. Aggregation
Die leistungsstarke Aggregationsfunktion von Elasticsearch ermöglicht uns die Durchführung von Statistiken, Analysen und Zusammenfassungen von Daten. Spring Data Elasticsearch bietet aggregationsbezogene APIs, damit wir verschiedene Analysevorgänge durchführen können.
AggregationBuilder aggregation = AggregationBuilders
.terms("genreAgg")
.field("genre.keyword")
.size(10);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.addAggregation(aggregation)
.build();
Aggregations aggregations = elasticsearchRestTemplate.query(searchQuery,
response -> response.getAggregations());
3. Filtern
Mit Spring Data Elasticsearch können wir verschiedene Filtervorgänge durchführen, um Dokumente herauszufiltern, die bestimmten Kriterien entsprechen. Dies kann uns helfen, die Teilmenge der interessierenden Daten zu extrahieren.
Criteria criteria = Criteria.where("genre").is("Fiction");
FilterQuery filterQuery = new SimpleFilterQuery(criteria);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withFilter(filterQuery)
.build();
List<Book> filteredBooks = elasticsearchRestTemplate.queryForList(searchQuery, Book.class);
Während wir unseren Blogbeitrag fortsetzen, wollen wir uns mit einigen fortgeschritteneren Themen befassen, um den Lesern zu einem umfassenderen Verständnis von Spring Data Elasticsearch zu verhelfen.
Andere Eigenschaften
1. Markieren Sie Suchergebnisse
Das Hervorheben von Ergebnissen, die einer Suchanfrage entsprechen, ist in Suchanwendungen häufig eine nützliche Funktion. Mit Spring Data Elasticsearch können wir passenden Text in Abfrageergebnissen hervorheben.
HighlightBuilder.Field highlightField = new HighlightBuilder.Field("title");
highlightField.preTags("<em>");
highlightField.postTags("</em>");
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("title", "spring framework"))
.withHighlightFields(highlightField)
.build();
SearchHits<Book> searchHits = elasticsearchRestTemplate.search(searchQuery, Book.class, IndexCoordinates.of("books"));
// 提取高亮信息
for (SearchHit<Book> searchHit : searchHits) {
List<String> highlightSnippets = searchHit.getHighlightField("title");
// 处理高亮信息
}
2. Geolokalisierungssuche
Elasticsearch verfügt über eine leistungsstarke Suchfunktion für geografische Standorte, mit der wir Dokumente anhand geografischer Koordinaten abfragen können. Spring Data Elasticsearch unterstützt auch Geolocation-Abfragen.
GeoPoint location = new GeoPoint(40.7128, -74.0060);
GeoDistanceQueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("location")
.point(location)
.distance(50, DistanceUnit.KILOMETERS);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.build();
SearchHits<Place> searchHits = elasticsearchRestTemplate.search(searchQuery, Place.class);
3. Benutzerdefinierter Analysator
Wenn wir den Textanalyseprozess anpassen müssen, um ihn besser an unsere Daten anzupassen, können wir mit Spring Data Elasticsearch benutzerdefinierte Analysetools definieren und verwenden.
@Setting(settingPath = "custom-analysis.json")
public class Book {
// ...
}
In diesem Beispiel haben wir über die Annotation @Setting
auf eine benutzerdefinierte Analysekonfigurationsdatei mit dem Namencustom-analysis.json
verwiesen.
Anwendungsfälle
Lassen Sie uns die Leistungsfähigkeit von Spring Data Elasticsearch anhand eines praktischen Anwendungsfalls demonstrieren.
Fall: Geolokalisierungssuche
Nehmen wir an, wir entwickeln eine Restaurant-Finder-Anwendung. Benutzer können einen Ort auf der Karte auswählen und nach Restaurants in der Nähe suchen. Dies ist ein typischer Anwendungsfall für die Geolokalisierungssuche.
@GetMapping("/restaurants")
public List<Restaurant> searchRestaurants(@RequestParam double latitude, @RequestParam double longitude) {
GeoPoint location = new GeoPoint(latitude, longitude);
GeoDistanceQueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("location")
.point(location)
.distance(5, DistanceUnit.KILOMETERS);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.build();
SearchHits<Restaurant> searchHits = elasticsearchRestTemplate.search(searchQuery, Restaurant.class);
// 返回附近的餐厅列表
return searchHits.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
}
In diesem Fall sucht der Benutzer nach nahegelegenen Restaurants, indem er Längen- und Breitengradkoordinaten angibt. Mit Spring Data Elasticsearch können wir solche Geolocation-Abfragen einfach durchführen.
4. Benutzerdefinierte Abfrage
Mit Spring Data Elasticsearch können wir benutzerdefinierte Abfragemethoden definieren, um erweiterte Abfragen basierend auf spezifischen Anforderungen durchzuführen. Dies kann durch die Erstellung von Schnittstellenmethoden und die Verwendung von @Query
-Annotationen erreicht werden.
@Query("{\"match\": {\"title\": \"?0\"}}")
List<Book> findByTitle(String title);
In diesem Beispiel erstellen wir eine benutzerdefinierte Abfragemethode und geben die JSON-Zeichenfolge der Abfrage über die Annotation @Query
an. Dadurch können wir komplexere Abfragen wie Volltextsuchen oder Fuzzy-Matching durchführen.
5. Verwenden von Spring's Page and Sort
Spring Data Elasticsearch unterstützt auch Page
- und Sort
-Objekte, was das Paginieren und Sortieren vereinfacht. Wir können diese Objekte in Abfragemethoden verwenden, um Paging und Sortierung von Ergebnissen zu implementieren.
Page<Book> findByGenre(String genre, Pageable pageable);
In diesem Beispiel verwenden wir das Pageable
-Objekt, um die Paging-Abfrage nach dem genre
-Feld zu implementieren.
6. Skriptabfrage
Elasticsearch ermöglicht uns die Verwendung von Skripten zur Durchführung komplexer Abfragen und Datentransformationen. Spring Data Elasticsearch unterstützt skriptbasierte Abfragen über @ScriptedField
-Annotationen.
@ScriptedField(name = "discountedPrice", script = "doc['price'].value * 0.9")
private Double discountedPrice;
In diesem Beispiel verwenden wir die Annotation @ScriptedField
, um ein berechnetes Feld mit dem Namen discountedPrice
basierend auf price
dem Wert zu erstellen des Feldes berechnet den Rabattpreis.
7. Multi-Index-Abfrage
Wenn unsere Daten auf mehrere Indizes verteilt sind, unterstützt Spring Data Elasticsearch auch Multi-Index-Abfragen. Wir können IndexCoordinates
verwenden, um mehrere Indizes anzugeben.
IndexCoordinates index1 = IndexCoordinates.of("index1");
IndexCoordinates index2 = IndexCoordinates.of("index2");
SearchHits<Book> searchHits = elasticsearchRestTemplate.search(query, Book.class, index1, index2);
Fall: Multi-Index-Abfrage
Angenommen, wir entwickeln eine Anwendung zur Nachrichtenaggregation, bei der Nachrichtendaten in verschiedenen Indizes gespeichert werden, wobei jeder Index einer anderen Nachrichtenquelle entspricht. Wir können die Multi-Index-Abfrage von Spring Data Elasticsearch verwenden, um Nachrichtendaten über mehrere Indizes hinweg abzurufen.
IndexCoordinates index1 = IndexCoordinates.of("news_source1");
IndexCoordinates index2 = IndexCoordinates.of("news_source2");
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.build();
SearchHits<NewsArticle> searchHits = elasticsearchRestTemplate.search(searchQuery, NewsArticle.class, index1, index2);
// 返回跨多个索引的新闻数据
List<NewsArticle> newsArticles = searchHits.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());
In diesem Fall haben wir zwei verschiedeneIndexCoordinates
s verwendet, um Abfragen über mehrere Indizes hinweg durchzuführen.
8. Mehrsprachige Unterstützung
Wenn unsere Anwendung die Volltextsuche in mehreren Sprachen unterstützen muss, stellt Elasticsearch mehrsprachige Analysatoren und Filter bereit. Mit Spring Data Elasticsearch können wir verschiedene Analysatoren für verschiedene Bereiche verwenden.
@Field(type = FieldType.Text, analyzer = "english_analyzer")
private String title;
@Field(type = FieldType.Text, analyzer = "chinese_analyzer")
private String content;
In diesem Beispiel verwenden wir den englischen Analysator für das Feld title
und den chinesischen Analysator für das Feld content
, um mehrsprachige Suchen zu ermöglichen.
Fall: Unterstützung mehrerer Sprachen
Angenommen, wir entwickeln ein mehrsprachiges Nachrichtenportal, in dem Nachrichtenartikel in verschiedenen Sprachen verfasst werden können. Wir können die Mehrsprachenunterstützung von Spring Data Elasticsearch nutzen, um eine Volltextsuche zu implementieren.
@Field(type = FieldType.Text, analyzer = "english_analyzer")
private String title;
@Field(type = FieldType.Text, analyzer = "french_analyzer")
private String content;
@Field(type = FieldType.Text, analyzer = "german_analyzer")
private String description;
In diesem Fall verwenden wir den englischen Parser für das Feld title
, den französischen Parser für das Feld content
und den französischen Parser für das Feld < /span>description
Field verwendet den deutschen Analysator, um die mehrsprachige Suche zu unterstützen.
9. Verbindungspoolverwaltung
In einer Produktionsumgebung ist es sehr wichtig, den Verbindungspool richtig zu konfigurieren, um eine effiziente Nutzung von Elasticsearch-Verbindungen sicherzustellen. Spring Data Elasticsearch bietet einige Konfigurationsoptionen zum Verwalten von Verbindungspools.
propertiesCopy codespring.data.elasticsearch.properties.http.max_connections=100
spring.data.elasticsearch.properties.http.max_connections_per_route=10
Durch die Konfigurationmax_connections
und max_connections_per_route
können wir die Größe des Verbindungspools steuern.
10. Versionskontrolle des Dokuments
In verteilten Systemen ist die Versionskontrolle von Dokumenten sehr wichtig, um Datenkonflikte und -verluste zu vermeiden. Elasticsearch bietet einen Mechanismus zur Dokumentversionskontrolle, der eine Dokumentversionsverwaltung durch @Version
Kommentare und @SeqNoPrimaryTerm
Kommentare erreichen kann.
@Version
private Long version;
@SeqNoPrimaryTerm
private SeqNoPrimaryTerm seqNoPrimaryTerm;
Mithilfe dieser Anmerkungen können wir die Version und Seriennummer eines Dokuments verfolgen, um Konflikte bei gleichzeitigen Vorgängen ordnungsgemäß zu lösen.
11. Suchvorschläge
Die Implementierung einer Suchvorschlagsfunktion ist eine Möglichkeit, das Benutzererlebnis zu verbessern, indem Benutzern in Echtzeit Vorschläge gemacht werden, während sie ihre Suchanfrage eingeben. Mit Spring Data Elasticsearch können wir Suchvorschlagsabfragen durchführen, um Vorschläge basierend auf Benutzereingaben bereitzustellen.
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
public List<String> suggestTerms(String input) {
CompletionSuggestionBuilder suggestionBuilder = SuggestBuilders.completionSuggestion("suggest")
.prefix(input)
.size(5);
SuggestBuilder suggest = new SuggestBuilder().addSuggestion("suggest-terms", suggestionBuilder);
SearchResponse searchResponse = elasticsearchRestTemplate.suggest(suggest, Book.class);
Suggest suggestResult = searchResponse.getSuggest();
if (suggestResult != null) {
List<Suggest.Suggestion.Entry.Option> options = suggestResult.getSuggestion("suggest-terms").getEntries().get(0).getOptions();
return options.stream().map(Suggest.Suggestion.Entry.Option::getText).collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
In diesem Beispiel haben wirCompletionSuggestionBuilder
verwendet, um eine Vorschlagsabfrage durchzuführen und Vorschläge zurückzugeben, die der Eingabe des Benutzers entsprechen.
Fall: Suchvorschläge
Nehmen wir an, wir entwickeln eine E-Commerce-Website und möchten den Benutzern Suchvorschläge bereitstellen, damit sie die gesuchten Produkte leichter finden können. Dies können wir mithilfe der Suchvorschlagsfunktion von Spring Data Elasticsearch erreichen.
@GetMapping("/suggest")
public List<String> suggestProducts(@RequestParam String query) {
return productService.suggestTerms(query);
}
In diesem Fall wird die vom Benutzer eingegebene Suchanfrage verwendet, um Suchvorschläge zu erhalten, die ihm bei der Suche nach relevanten Produkten helfen.
Großer Koffer für eine E-Commerce-Plattform
Fallhintergrund
Angenommen, es gibt ein globales E-Commerce-Unternehmen. Es ist in mehreren Ländern und Regionen tätig und verfügt über einen riesigen Produktkatalog, Millionen von Benutzern und Tausende gleichzeitiger Online-Transaktionen. Um ein so großes Geschäft abzuwickeln, verlassen sie sich auf Elasticsearch als Such- und Produktempfehlungsmaschine.
Fall Analyse
Bei dieser groß angelegten E-Commerce-Plattform spielt Spring Data Elasticsearch eine Schlüsselrolle:
- Volltextsuche: Nutzer können die Suchmaschine nutzen, um Produkte schnell zu finden. Mit Spring Data Elasticsearch wird eine leistungsstarke Volltextsuchmaschine erstellt, die Funktionen wie die automatische Korrektur von Rechtschreibfehlern, die Empfehlung verwandter Suchbegriffe und Suchvorschläge unterstützt.
- Produktempfehlung: Die Plattform nutzt den Browser- und Kaufverlauf der Nutzer sowie Empfehlungsalgorithmen wie kollaborative Filterung, um Nutzern personalisierte Produktempfehlungen zu geben. Spring Data Elasticsearch wird zum Speichern und Abrufen von Produkt- und Benutzerverhaltensdaten verwendet.
- Bestands- und Preisaktualisierungen in Echtzeit: E-Commerce-Plattformen müssen den Bestandsstatus und den Preis von Waren zeitnah aktualisieren. Die Echtzeit-Indexaktualisierungsfunktion von Spring Data Elasticsearch gewährleistet die zeitnahe Verfügbarkeit von Daten.
- Länderübergreifende internationale Suche: Aufgrund des länderübergreifenden Betriebs können Benutzer in mehreren Sprachen nach Produkten suchen. Spring Data Elasticsearch unterstützt die mehrsprachige Volltextsuche und stellt lokalisierte Suchergebnisse basierend auf dem Standort des Benutzers bereit.
- Überwachung und Leistungsoptimierung: Die E-Commerce-Plattform muss die Leistung und den Zustand des Elasticsearch-Clusters regelmäßig überwachen und eine Leistungsoptimierung durchführen. Spring Data Elasticsearch integriert Überwachungstools und Leistungsanalyse-Plugins, um diese Ziele zu erreichen.
- Auftragsverfolgung: Benutzer können den Status ihrer Bestellungen in Echtzeit verfolgen. Spring Data Elasticsearch wird zum Speichern und Abrufen von Bestelldaten verwendet, um schnelle und Echtzeit-Auftragsverfolgungsdienste bereitzustellen.
Architektur-Design
In der Architektur dieser E-Commerce-Plattform umfassen Elasticsearch-Cluster normalerweise mehrere Knoten, um Hochverfügbarkeit und horizontale Erweiterung zu unterstützen. Spring Data Elasticsearch wird mit Spring Boot verwendet, um über eine RESTful-API mit dem Elasticsearch-Cluster zu kommunizieren. Darüber hinaus kann die Plattform auch andere Technologie-Stacks wie Redis-Caching, Nachrichtenwarteschlangen usw. nutzen, um Leistung und Skalierbarkeit zu verbessern.
Projektherausforderungen
Bei einer so großen E-Commerce-Plattform steht die Verwendung von Spring Data Elasticsearch vor den folgenden Herausforderungen:
- Hohe Auslastung und Parallelität: Die Verarbeitung hoher Auslastung und gleichzeitiger Anfragen von Millionen von Benutzern erfordert hochoptimierte Suchmaschinen und Datenspeicher.
- Datenkonsistenz: Die Sicherstellung der Konsistenz von Produktbestands-, Preis- und Bestelldaten ist ein komplexes Thema, das einen effektiven Synchronisierungsmechanismus erfordert.
- Echtzeitanforderungen: Echtzeitaktualisierungen von Bestands- und Preisinformationen erfordern schnelle Indexaktualisierungen.
- Mehrsprachigkeit und Lokalisierung: Die Unterstützung mehrsprachiger Suchen und die Bereitstellung lokalisierter Ergebnisse erfordert eine detaillierte Konfiguration und Verarbeitung.
- Überwachung und Wartung: Die Überwachung des Zustands und der Leistung großer Elasticsearch-Cluster erfordert spezielle Tools und Vorgehensweisen.
Codebeispiel
Für große Projekte kann ich hier nicht den vollständigen Code bereitstellen, da solche Projekte meist sehr komplex sind und eine Vielzahl an Codedateien und Abhängigkeiten enthalten. Ich habe es zu einem logischen Beispiel vereinfacht, das zeigt, wie man mit Spring Data Elasticsearch grundlegende Volltextsuch- und Speichervorgänge durchführt.
Stellen Sie zunächst sicher, dass unser Spring Boot-Projekt ordnungsgemäß eingerichtet ist und die Spring Data Elasticsearch-Abhängigkeit enthält.
Projektstruktur
Erstellen wir zunächst die Projektstruktur:
cssCopy codemy-ecommerce-project/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ ├── com/
│ │ │ │ ├── example/
│ │ │ │ │ ├── controller/
│ │ │ │ │ │ ├── ProductController.java
│ │ │ │ │ │ ├── UserController.java
│ │ │ │ │ ├── model/
│ │ │ │ │ │ ├── Product.java
│ │ │ │ │ │ ├── User.java
│ │ │ │ │ ├── repository/
│ │ │ │ │ │ ├── ProductRepository.java
│ │ │ │ │ │ ├── UserRepository.java
│ │ │ │ │ ├── service/
│ │ │ │ │ │ ├── ProductService.java
│ │ │ │ │ │ ├── UserService.java
│ ├── resources/
│ │ ├── application.properties
Entitätsklasse
Erstellen SieProduct
und User
Entitätsklassen, um Produkte bzw. Benutzer darzustellen:
// Product.java
@Entity
@Document(indexName = "products")
public class Product {
@Id
private String id;
private String name;
private double price;
// 省略构造函数、getter和setter
}
// User.java
@Entity
@Document(indexName = "users")
public class User {
@Id
private String id;
private String username;
// 省略构造函数、getter和setter
}
Repository-Schnittstelle
ErstellenProductRepository
und UserRepository
Schnittstellen zum Ausführen von CRUD-Operationen:
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
List<Product> findByNameContaining(String name);
}
public interface UserRepository extends ElasticsearchRepository<User, String> {
Optional<User> findByUsername(String username);
}
Serviceklasse
Erstellen SieProductService
und UserService
Klassen zum Ausführen von Geschäftslogik:
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public void saveProduct(Product product) {
productRepository.save(product);
}
public List<Product> searchProductsByName(String name) {
return productRepository.findByNameContaining(name);
}
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void saveUser(User user) {
userRepository.save(user);
}
public Optional<User> findUserByUsername(String username) {
return userRepository.findByUsername(username);
}
}
Regler
Erstellen SieProductController
und UserController
Controller zur Verarbeitung von HTTP-Anfragen:
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping
public ResponseEntity<?> addProduct(@RequestBody Product product) {
productService.saveProduct(product);
return ResponseEntity.ok().build();
}
@GetMapping("/search")
public ResponseEntity<List<Product>> searchProducts(@RequestParam String query) {
List<Product> products = productService.searchProductsByName(query);
return ResponseEntity.ok(products);
}
}
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<?> addUser(@RequestBody User user) {
userService.saveUser(user);
return ResponseEntity.ok().build();
}
@GetMapping("/search")
public ResponseEntity<User> searchUser(@RequestParam String username) {
Optional<User> user = userService.findUserByUsername(username);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
Hauptklasse der Anwendung
Fügen Sie in der Hauptklasse Ihrer Spring Boot-Anwendung die folgenden Anmerkungen hinzu, um die automatische Konfiguration des Elasticsearch-Warehouses zu ermöglichen und die Elasticsearch-Verbindung zu konfigurieren:
@SpringBootApplication
@EnableElasticsearchRepositories(basePackages = "com.example.repository")
public class MyElasticsearchApplication {
public static void main(String[] args) {
SpringApplication.run(MyElasticsearchApplication.class, args);
}
}
Dieses Beispielprojekt enthält mehr Geschäftslogik und Funktionalität, einschließlich Logik für Produktverwaltung, Benutzersuche und Auftragsabwicklung. Wir können es entsprechend den Anforderungen des Projekts weiter erweitern, indem wir weitere Entitätsklassen, benutzerdefinierte Abfragen, Sicherheit, Leistungsoptimierung und -überwachung usw. hinzufügen. Hoffentlich erfüllt dieses Beispiel unsere Anforderungen und bietet detailliertere Beispiele für Spring Data Elasticsearch.