Spring Boot එක්ක Solr Search | Advanced Search Solutions for Java Apps - SC Guide

Spring Boot එක්ක Solr Search | Advanced Search Solutions for Java Apps - SC Guide

Supercharging Search with Spring Boot and Solr: An SC Guide

Supercharging Search with Spring Boot and Solr: An SC Guide

ආයුබෝවන් කට්ටියට! කොහොමද? ඔයාලා හැමෝම Java Development, ඒ වගේම Spring Boot එක්ක වැඩ කරනවා ඇති නේද? අද අපි කතා කරන්න යන්නේ ගොඩක් වැදගත්, ඒ වගේම ඕනෑම Application එකක අනිවාර්යයෙන්ම තියෙන්න ඕන Feature එකක් ගැන. ඒ තමයි Search Functionality එක. ඔයාටත් ලොකු Data Set එකක් ඇතුළේ ඉක්මනට ඕන කරන දේවල් හොයාගන්න ඕන නම්, මේ Article එක ඔයාටම තමයි.

ගොඩක් වෙලාවට අපි Database එකේ LIKE Queries දාලා Search කරනවනේ. ඒත්, ඒක හැමවෙලේම හොඳ විසඳුමක් නෙවෙයි. විශේෂයෙන්ම Data ගොඩක් වැඩි වෙනකොට, Performance ප්‍රශ්න එනවා. අන්න ඒ වගේ තැන්වලදී තමයි Solr වගේ Dedicated Search Engines අපිට ගොඩක් උදව් වෙන්නේ. ඉතින්, අද අපි Spring Boot Application එකක් ඇතුළේ Solr Use කරලා Advanced Search Solution එකක් හදාගන්නේ කොහොමද කියලා පියවරෙන් පියවර බලමු. හැමෝම ලෑස්තිද?

Solr කියන්නේ මොකක්ද? (What is Solr?)

සරලවම කිව්වොත්, Solr කියන්නේ Apache Software Foundation එකෙන් දියුණු කරපු Open Source Search Platform එකක්. මේක ගොඩනගලා තියෙන්නේ Apache Lucene කියන Library එක උඩ. Lucene කියන්නේ Powerful Indexing සහ Search Capabilities තියෙන Library එකක්. Solr මේ Lucene Library එකට උඩින් REST-like APIs, Faceted Search, Highlighting, Clustering වගේ ගොඩක් Features එකතු කරනවා.

ඇයි අපි Solr පාවිච්චි කරන්නේ? මෙන්න ප්‍රධාන හේතු කීපයක්:

  • Full-Text Search: සාමාන්‍ය Database එකකදි වචන අතර Query කරන්න අමාරුයි. Solr එකේ Natural Language Processing (NLP) Capabilities තියෙන නිසා වචන, වාක්‍ය ඇතුළේ Search කරන්න පුළුවන්.
  • Performance: Solr කියන්නේ High Performance Search Engine එකක්. ලොකු Data ප්‍රමාණයක් ඇතුළේ ඉක්මනින් Search කරන්න පුළුවන්. Indexing කියන ක්‍රමවේදය නිසා තමයි මේ වේගය ලැබෙන්නේ.
  • Scalability: Solr Cluster එකක් විදියට setup කරන්න පුළුවන්. ඒ කියන්නේ අවශ්‍යතාවය අනුව Search Capacity එක වැඩි කරගන්න පුළුවන්.
  • Rich Features: Faceted Search (ප්‍රතිඵල filter කරන්න), Highlighting (Search කරපු වචන ඉස්මතු කරලා පෙන්නන්න), Auto-suggest/Autocomplete වගේ දේවල් Solr එකේ Built-in තියෙනවා.

හරි, දැන් අපි Solr කියන්නේ මොකක්ද කියලා තේරුම් ගත්තා. ඊළඟට අපි බලමු මේක අපේ System එකට Integrate කරගන්නේ කොහොමද කියලා.

Solr Set up කරමු (Let's Set up Solr)

මුලින්ම අපි Solr Download කරගෙන Local Machine එකේ Setup කරගමු. මේ පියවර ඔයාගේ OS එක අනුව පොඩි වෙනස්කම් වෙන්න පුළුවන්. මම මෙතනදි Windows හෝ Linux වලට පොදු විදියට පැහැදිලි කරන්නම්.

1. Solr Download කරගමු

Solr Download කරන්න පුළුවන් මේ Link එකෙන්: Apache Solr Downloads. Latest Stable Version එක Download කරගන්න. Zip file එකක් එයි. ඒක ඔයා කැමති තැනකට Extract කරගන්න. උදාහරණයක් විදියට, C:\solr (Windows) හෝ /opt/solr (Linux) වගේ තැනකට.

2. Solr Start කරමු

Extract කරපු Folder එකේ bin කියන Folder එක ඇතුළේ Solr Start කරන්න අවශ්‍ය Scripts තියෙනවා. Command Prompt එකක් (CMD) හෝ Terminal එකක් Open කරලා ඒ Folder එකට ගිහින් පහත Command එක Run කරන්න:

cd C:\solr\solr-9.x.x\bin  # ඔයාගේ version එකට අනුව path එක වෙනස් වෙන්න පුළුවන්
solr start -p 8983

Solr සාර්ථකව Start වුණා නම්, ඔයාට Message එකක් පෙනෙයි. දැන් ඔයාගේ Browser එකේ http://localhost:8983/solr කියන URL එකට ගිහින් Solr Admin UI එක බලන්න පුළුවන්.

3. Solr Core එකක් හදමු

Solr එකේ Data ගබඩා කරන්නේ "Cores" ඇතුළේ. Core එකක් කියන්නේ වෙනම Index එකක්. අපි අපේ Application එකට Core එකක් හදාගමු. මම මේකට product_data කියලා නමක් දෙන්නම්. Terminal එකේ පහත Command එක Run කරන්න:

solr create -c product_data

මේ Command එක Run කලාම product_data කියන Core එක හැදෙනවා. Solr Admin UI එකට ගිහින් "Core Admin" යටතේ බලනකොට මේ Core එක පෙනෙන්න ඕන.

4. Schema එක Configure කරමු

Solr එකට Data දාන්න කලින්, අපි Solr Core එකේ Schema එක Define කරන්න ඕන. Schema එක කියන්නේ අපි Index කරන්න බලාපොරොත්තු වෙන Data වල Fields මොනවද, ඒවයේ Data Types මොනවද වගේ විස්තර. මේක managed-schema file එකෙන් තමයි configure කරන්නේ. මේ File එක තියෙන්නේ ඔයාගේ Solr Home Directory එකේ server/solr/product_data/conf/managed-schema කියන Path එකේ.

අපි Product එකක් Index කරන්න අවශ්‍ය වෙන id, name, description, price වගේ Fields කීපයක් මේ Schema එකට Add කරගමු. Text Editor එකකින් managed-schema file එක Open කරලා <fields> tag එක ඇතුළට මේ Lines ටික Add කරන්න:

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="name" type="text_general" indexed="true" stored="true"/>
<field name="description" type="text_general" indexed="true" stored="true"/>
<field name="price" type="pfloat" indexed="true" stored="true"/>
<!-- Add other fields as needed -->

මේ Changes Save කරලා Solr Core එක Reload කරන්න ඕන. Solr Admin UI එකේ Core Admin එකට ගිහින් product_data Core එක Select කරලා "Reload" කරන්න, නැත්නම් Solr Server එක Restart කරන්න.

Spring Boot එක්ක Solr සම්බන්ධ කරමු (Connecting Solr with Spring Boot)

දැන් අපිට Solr Server එකක් Ready. ඊළඟට අපි බලමු Spring Boot Application එකක් ඇතුළේ Solr එක්ක වැඩ කරන්නේ කොහොමද කියලා.

1. Dependencies Add කරමු

මුලින්ම, ඔයාගේ Spring Boot Project එකේ pom.xml file එකට Solr Dependencies Add කරන්න ඕන. අපි Spring Data Solr Use කරන නිසා, ඒකේ Starter Dependency එක Add කරමු:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>

2. Solr Connection Properties Configure කරමු

ඊළඟට, application.properties (හෝ application.yml) file එකට Solr Server එකට connect වෙන්න අවශ්‍ය Configuration Add කරන්න. අපි කලින් Solr Start කරද්දී 8983 Port එක Use කරපු නිසා, ඒකම මෙතනදිත් දෙමු.

# application.properties
spring.data.solr.host=http://localhost:8983/solr
spring.data.solr.repositories.enabled=true # Spring Data Solr Repositories enable කරන්න

දැන් Spring Boot Application එක Solr Server එකට Connect වෙන්න Ready.

3. Solr Document Class එකක් හදමු

අපි Database එකේ Entities හදනවා වගේම Solr එකට Index කරන්න අවශ්‍ය Data Model එකක් හදාගන්න ඕන. මේක "Solr Document" එකක් විදියට හඳුන්වනවා. අපේ product_data Core එකට දාන්න අවශ්‍ය Product එක නියෝජනය කරන්න Class එකක් හදමු.

package com.example.solr.model;

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.solr.core.mapping.SolrDocument;
import org.springframework.data.solr.core.mapping.Indexed;

@SolrDocument(solrCoreName = "product_data") // Solr Core Name එක මෙතන දෙනවා
public class Product {

    @Field @Indexed(name = "id", type = "string")
    private String id;

    @Field @Indexed(name = "name", type = "text_general")
    private String name;

    @Field @Indexed(name = "description", type = "text_general")
    private String description;

    @Field @Indexed(name = "price", type = "pfloat")
    private Float price;

    // Constructors, Getters and Setters

    public Product() {
    }

    public Product(String id, String name, String description, Float price) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.price = price;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Product{" +
               "id='" + id + '\'' +
               ", name='" + name + '\'' +
               ", description='" + description + '\'' +
               ", price=" + price +
               '}';
    }
}

මෙහිදී, @SolrDocument Annotation එකෙන් Solr Core එක සහ Class එක අතර Mapping එක සිදු කරනවා. @Field Annotation එක Solr Document එකේ Field එකක් කියලා පෙන්නනවා. ඒ වගේම @Indexed Annotation එකෙන් Solr Schema එකේ Field Name එක සහ Type එක define කරනවා. මේවා අපි කලින් managed-schema එකට දැම්ම Field Names සහ Types එක්ක Match වෙන්න ඕන, හරිද?

4. Solr Repository Interface එකක් හදමු

Spring Data JPA වගේම Spring Data Solr වලටත් Repository Pattern එක Support කරනවා. අපිට Solr Operations කරන්න වෙනම Repository Interface එකක් හදාගන්න පුළුවන්.

package com.example.solr.repository;

import com.example.solr.model.Product;
import org.springframework.data.solr.repository.SolrCrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ProductRepository extends SolrCrudRepository<Product, String> {

    List<Product> findByNameContaining(String name); // product name එකෙන් search කරන්න
    List<Product> findByDescriptionContaining(String description); // description එකෙන් search කරන්න
    List<Product> findByNameOrDescriptionContaining(String name, String description); // නම හෝ විස්තරය අනුව search කරන්න
    List<Product> findByPriceBetween(Float minPrice, Float maxPrice); // මිල පරාසයක් තුල search කරන්න
}

SolrCrudRepository Interface එක Extend කරනකොට Basic CRUD Operations (Save, Find by ID, Delete) අපිට Auto-generate වෙනවා. ඒ වගේම Method Naming Conventions පාවිච්චි කරලා Custom Queries හදාගන්නත් පුළුවන්. උදාහරණයක් විදියට, findByNameContaining වගේ Method එකක් Automatic Solr Query එකක් බවට Convert වෙනවා.

Data Indexing කරමු (Let's Index Data)

දැන් අපි Solr එකට Data Add කරන්නේ කොහොමද කියලා බලමු. මේක කරන්න අපිට Service Layer එකක් හදාගන්න පුළුවන්.

package com.example.solr.service;

import com.example.solr.model.Product;
import com.example.solr.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public Product saveProduct(Product product) {
        if (product.getId() == null || product.getId().isEmpty()) {
            product.setId(UUID.randomUUID().toString()); // අලුත් id එකක් generate කරනවා
        }
        return productRepository.save(product);
    }

    public List<Product> saveAllProducts(List<Product> products) {
        List<Product> savedProducts = new ArrayList<>();
        for (Product product : products) {
            savedProducts.add(saveProduct(product)); // හැම Product එකක්ම save කරනවා
        }
        return savedProducts;
    }

    // ... other methods like findById, deleteAll, etc.
}

මේ ProductService එකෙන් ProductRepository එක Use කරලා Products Solr එකට Save කරනවා. අපි Simple Controller එකක් හදලා මේ Service එකට Data ටිකක් දාලා බලමු.

package com.example.solr.controller;

import com.example.solr.model.Product;
import com.example.solr.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    @PostMapping("/index")
    public List<Product> indexSampleProducts() {
        List<Product> products = Arrays.asList(
            new Product(null, "Laptop Pro X", "Powerful laptop for professionals with 16GB RAM and 512GB SSD.", 1200.00F),
            new Product(null, "Wireless Mouse Z", "Ergonomic wireless mouse with adjustable DPI.", 25.50F),
            new Product(null, "USB-C Hub Elite", "Multi-port USB-C hub with HDMI, USB 3.0, and Power Delivery.", 50.00F),
            new Product(null, "Gaming Keyboard RGB", "Mechanical gaming keyboard with customizable RGB lighting.", 80.00F),
            new Product(null, "External SSD 1TB", "Portable 1TB SSD for fast data transfer.", 150.00F),
            new Product(null, "Laptop Stand Aluminum", "Adjustable aluminum stand for laptops.", 35.00F)
        );
        return productService.saveAllProducts(products);
    }

    // ... Querying endpoints will go here
}

දැන් ඔයාට Postman වගේ Tool එකකින් http://localhost:8080/products/index කියන URL එකට POST Request එකක් යැව්වොත්, මේ Sample Products ටික Solr එකේ Index වෙනවා. Solr Admin UI එකේ product_data Core එකේ Query Tab එකට ගිහින් q=*:* කියලා දාලා Execute කලාම, Index වෙච්ච Data ටික බලන්න පුළුවන්.

Data Query කරමු (Let's Query Data)

අවසාන වශයෙන්, අපි Index කරපු Data Search කරන්නේ කොහොමද කියලා බලමු. අපේ ProductRepository එකේ Custom Query Methods දාලා තියෙනවනේ. අපි ඒක Controller එකෙන් Call කරලා බලමු.

package com.example.solr.controller;

import com.example.solr.model.Product;
import com.example.solr.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    // ... (indexSampleProducts method)

    @GetMapping("/search/name")
    public List<Product> searchByName(@RequestParam String query) {
        return productService.findByNameContaining(query);
    }

    @GetMapping("/search/description")
    public List<Product> searchByDescription(@RequestParam String query) {
        return productService.findByDescriptionContaining(query);
    }

    @GetMapping("/search/all")
    public List<Product> searchAllFields(@RequestParam String query) {
        // මේක ProductRepository එකේ findByNameOrDescriptionContaining method එකෙන් ගන්න පුළුවන්.
        // ඒත්, මේක Spring Data Solr වල @Query annotation එක පාවිච්චි කරලා ගොඩක් Powerful Query එකක් විදියටත් ලියන්න පුළුවන්.
        // උදාහරණයක් විදියට:
        // @Query("name:*?0* OR description:*?0*")
        // Page<Product> findByCustomQuery(String searchTerm, Pageable pageable);
        // දැනට අපි repo එකේ තියෙන simple method එක පාවිච්චි කරමු.
        return productService.findByNameOrDescriptionContaining(query, query);
    }

    @GetMapping("/search/price")
    public List<Product> searchByPriceRange(@RequestParam Float min, @RequestParam Float max) {
        return productService.findByPriceBetween(min, max);
    }
}

දැන් ඔයාට මේ Search Endpoints Call කරලා Data Search කරන්න පුළුවන්:

  • http://localhost:8080/products/search/name?query=laptop
  • http://localhost:8080/products/search/description?query=ram
  • http://localhost:8080/products/search/all?query=keyboard
  • http://localhost:8080/products/search/price?min=20&max=60

මේ Query Methods මගින් Solr එකේ Full-Text Search හැකියාව උපරිමයෙන් ප්‍රයෝජනයට ගන්න පුළුවන්. text_general type එකට දාලා තියෙන Fields වලට Search කරද්දී Solr එක Automatic Tokenization, Stemming වගේ දේවල් කරනවා. ඒ නිසා "laptops" කියලා Search කරාම "laptop" කියන Results එනවා වගේ Smart Search Results ලැබෙනවා.

නිගමනය (Conclusion)

හරි, අද අපි Spring Boot Application එකක් ඇතුළේ Apache Solr Integrate කරලා Powerful Search Solution එකක් හදාගන්නේ කොහොමද කියලා කතා කළා. Solr Setup කරන එකේ ඉඳන් Spring Boot එක්ක Connect කරලා Data Index කරන, ඒ වගේම Query කරන හැටි පියවරෙන් පියවර පැහැදිලි කළා. ඔයාටත් ලොකු Data Set එකක් එක්ක වැඩ කරන්න තියෙනවා නම්, User Experience එක වැඩි දියුණු කරන්න Advanced Search Solution එකක් ඕන නම්, Solr කියන්නේ නියම තෝරාගැනීමක්.

මේ Article එකේ තියෙන Concepts තේරුම් අරන්, ඔයාගේ Project වලට Solr Integrate කරලා බලන්න. මොනවා හරි ප්‍රශ්න තියෙනවා නම්, Comment Section එකේ අනිවාර්යයෙන්ම අහන්න. ඒ වගේම මේ Article එක ඔයාට වටිනවා නම්, Share කරන්නත් අමතක කරන්න එපා. තවත් මේ වගේම වැදගත් Technical Article එකකින් හමුවෙමු! සුභ දවසක්!