Úvod do režimu dlhodobého spánku

1. Prehľad

V tomto článku si rozoberieme základné informácie o Hibernate Search, o tom, ako ho nakonfigurovať, a implementujeme niekoľko jednoduchých dotazov.

2. Základy vyhľadávania v režime dlhodobého spánku

Kedykoľvek musíme implementovať funkciu fulltextového vyhľadávania, vždy je výhodou použitie nástrojov, s ktorými sa už dobre orientujeme.

V prípade, že pre ORM už používame režim dlhodobého spánku a JPA, sme už len jeden krok od vyhľadávania režimu dlhodobého spánku.

Hibernate Search integruje Apache Lucene, vysoko výkonnú a rozšíriteľnú fulltextovú knižnicu vyhľadávacieho nástroja napísanú v prostredí Java. To kombinuje silu Lucene s jednoduchosťou Hibernate a JPA.

Jednoducho povedané, do našich doménových tried musíme pridať niekoľko ďalších anotácií a nástroj sa postará napríklad o synchronizáciu databázy / indexu.

Hibernate Search tiež poskytuje integráciu Elasticsearch; keďže je to však stále v experimentálnej fáze, zameriame sa tu na Lucene.

3. Konfigurácie

3.1. Maven závislosti

Predtým, ako začneme, musíme do nášho systému najskôr pridať potrebné závislosti pom.xml:

 org.hibernate hibernate-search-orm 5.8.2.Final 

Kvôli jednoduchosti použijeme ako našu databázu H2:

 com.h2database h2 1.4.196 

3.2. Konfigurácie

Musíme tiež určiť, kam má index Lucene uložiť.

To možno urobiť prostredníctvom ubytovacieho zariadenia hibernate.search.default.directory_provider.

Vyberieme si systém súborov, čo je pre náš prípad použitia najpriamejšia možnosť. Viac možností je uvedených v oficiálnej dokumentácii. Súborový systém-master/súborový systém-slave a infinispan sú pozoruhodné pre klastrované aplikácie, kde sa index musí synchronizovať medzi uzlami.

Musíme tiež definovať predvolený základný adresár, do ktorého sa budú ukladať indexy:

hibernate.search.default.directory_provider = súborový systém hibernate.search.default.indexBase = / data / index / predvolené

4. Modelové triedy

Po konfigurácii sme teraz pripravení špecifikovať náš model.

Nad anotácie JPA @Entity a @ Tabuľka, musíme pridať @Indexed anotácia. Hibernate Search to povie entite Výrobok sa indexujú.

Potom musíme definovať požadované atribúty ako prehľadávateľné pridaním a @Lúka anotácia:

@Entity @Indexed @Table (name = "product") verejná trieda Produkt {@Id private int id; @Field (termVector = TermVector.YES) private String productName; @Field (termVector = TermVector.YES) súkromný popis reťazca; @Field súkromná int pamäť; // zakladatelia, zakladatelia a konštruktory}

The termVector = TermVector.ANO pre dopyt „Viac podobných“ sa bude neskôr vyžadovať atribút.

5. Vytvorenie indexu Lucene

Pred spustením skutočných dotazov musíme najskôr spustiť Lucene, aby vytvoril index:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager (entityManager); fullTextEntityManager.createIndexer (). startAndWait ();

Po tomto počiatočnom zostavení sa program Hibernate Search postará o aktualizáciu indexu. I. e. prostredníctvom entity môžeme vytvárať, manipulovať a mazať entity EntityManager ako zvyčajne.

Poznámka: musíme sa ubezpečiť, že entity sú plne oddané databáze, kým ich Lucene nebude môcť objaviť a indexovať (mimochodom, to je tiež dôvod, prečo sa úvodný import testovacích údajov v našich príkladoch testovacích prípadov kódu dodáva vo vyhradenom testovacom prípade JUnit s poznámkami @Commit).

6. Vytváranie a vykonávanie dotazov

Teraz sme pripravení na vytvorenie nášho prvého dotazu.

V nasledujúcej časti ukážeme si všeobecný pracovný postup na prípravu a vykonanie dotazu.

Potom vytvoríme niekoľko príkladov dotazov na najdôležitejšie typy dotazov.

6.1. Všeobecný pracovný postup pre vytváranie a vykonávanie dotazov

Príprava a vykonávanie dotazu vo všeobecnosti pozostáva zo štyroch krokov:

V kroku 1 musíme získať JPA FullTextEntityManager a z toho a QueryBuilder:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager (entityManager); QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory () .buildQueryBuilder () .forEntity (Product.class) .get ();

V kroku 2 vytvoríme dotaz Lucene prostredníctvom dotazu Hibernate DSL:

org.apache.lucene.search.Query query = queryBuilder .keyword () .onField ("productName") .matching ("iphone") .createQuery ();

V kroku 3 zabalíme dopyt Lucene do dotazu dlhodobého spánku:

org.hibernate.search.jpa.FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery (dopyt, Product.class);

Nakoniec v kroku 4 vykonáme dopyt:

Zoznam výsledkov = jpaQuery.getResultList ();

Poznámka: Lucene predvolene triedi výsledky podľa dôležitosti.

Kroky 1, 3 a 4 sú rovnaké pre všetky typy dotazov.

V ďalšom sa zameriame na krok 2, t. e. ako vytvárať rôzne typy dotazov.

6.2. Dotazy na kľúčové slová

Najzákladnejším prípadom použitia je hľadanie konkrétneho slova.

Toto sme vlastne urobili už v predchádzajúcej časti:

Dotaz kľúčové slovoQuery = queryBuilder .keyword () .onField ("productName") .matching ("iphone") .createQuery ();

Tu, kľúčové slovo () určuje, že hľadáme jedno konkrétne slovo, onField () povie Lucene, kde hľadať a zodpovedajúce () čo hľadať.

6.3. Fuzzy dotazy

Fuzzy dotazy fungujú ako dotazy na kľúčové slová, až na to môžeme definovať hranicu „fuzziness“, nad ktorou Lucene prijme tieto dva výrazy ako zhodné.

Autor: withEditDistanceUpTo (), môžeme definovať, ako veľmi sa môže výraz líšiť od druhého. Môže byť nastavený na 0, 1 a 2, pričom predvolená hodnota je 2 (Poznámka: toto obmedzenie vyplýva z implementácie Lucene).

Autor: withPrefixLength (), môžeme definovať dĺžku predpony, ktorú bude fuzziness ignorovať:

Dotaz fuzzyQuery = queryBuilder .keyword () .fuzzy () .withEditDistanceUpTo (2) .withPrefixLength (0) .onField ("productName") .matching ("iPhaen") .createQuery ();

6.4. Zástupné dotazy

Hibernate Search nám tiež umožňuje vykonávať dotazy so zástupnými znakmi, t.j. e. dotazy, pre ktoré nie je známa časť slova.

Na tento účel môžeme použiť „?” pre jeden znak a „*” pre ľubovoľnú postupnosť znakov:

Dotaz wildcardQuery = queryBuilder .keyword () .wildcard () .onField ("productName") .matching ("Z *") .createQuery ();

6.5. Frázové dotazy

Ak chceme vyhľadať viac ako jedno slovo, môžeme použiť frázové dotazy. Môžeme sa pozrieť za presné alebo za približné vety, použitím fráza () a withSlop (), Ak je to nevyhnutné. Faktor slop definuje počet ďalších slov povolených vo vete:

Query phraseQuery = queryBuilder .phrase () .withSlop (1) .onField ("description") .sentence ("s bezdrôtovým nabíjaním") .createQuery ();

6.6. Jednoduché dotazy na reťazec

Pri predchádzajúcich typoch dotazov sme museli explicitne určiť typ dotazu.

Ak chceme používateľovi poskytnúť viac energie, môžeme použiť jednoduché dotazy na reťazce dotazov: tým môže definovať svoje vlastné dotazy za behu.

Podporované sú nasledujúce typy dotazov:

  • boolean (A použitie „+“, ALEBO použitie „|“, NIE použitie „-“)
  • prefix (prefix *)
  • fráza („nejaká fráza“)
  • prednosť (s použitím zátvoriek)
  • fuzzy (fuzy ~ 2)
  • operátor v blízkosti operátora pre frázové dotazy („nejaká fráza“ ~ 3)

Nasledujúci príklad by kombinoval fuzzy, frázové a booleovské dotazy:

Dotaz simpleQueryStringQuery = queryBuilder .simpleQueryString () .onFields ("productName", "description") .matching ("Aple ~ 2 + \" iPhone X \ "+ (256 | 128)")) .createQuery ();

6.7. Rozsahové dotazy

Vyhľadajte rozsahové dotazy ahodnota medzi danými hranicami. Toto je možné použiť na čísla, dátumy, časové značky a reťazce:

Dotaz rangeQuery = queryBuilder .range () .onField ("pamäť") .z (64) .to (256) .createQuery ();

6.8. Viac podobných otázok

Náš posledný typ dopytu je „Viac podobných" - dopyt. Za týmto účelom poskytujeme subjekt, a Režim dlhodobého spánku vráti zoznam s podobnými entitami, každý s podobným skóre.

Ako už bolo spomenuté, termVector = TermVector.ANO V tomto prípade sa vyžaduje atribút v našej modelovej triede: hovorí Lucene, aby počas indexovania ukladal frekvenciu každého výrazu.

Na základe toho sa vypočíta podobnosť v čase vykonania dotazu:

Dopytovať moreLikeThisQuery = queryBuilder .moreLikeThis () .comparingField ("productName"). BoostedTo (10f) .andField ("description"). BoostedTo (1f) .toEntity (entity) .createQuery (); Zoznam výsledkov = (Zoznam) fullTextEntityManager .createFullTextQuery (moreLikeThisQuery, Product.class) .setProjection (ProjectionConstants.THIS, ProjectionConstants.SCORE) .getResultList ();

6.9. Hľadáte viac ako jedno pole

Doteraz sme vytvárali dotazy na prehľadávanie iba jedného atribútu pomocou príkazu onField ().

V závislosti od prípadu použitia môžeme prehľadať aj dva alebo viac atribútov:

Dotaz luceneQuery = queryBuilder .keyword () .onFields ("productName", "description") .matching (text) .createQuery ();

Navyše, môžeme určiť každý atribút, ktorý sa má prehľadať osobitne, napr. g. ak chceme definovať podporu pre jeden atribút:

Dopytovať moreLikeThisQuery = queryBuilder .moreLikeThis () .comparingField ("productName"). BoostedTo (10f) .andField ("description"). BoostedTo (1f) .toEntity (entity) .createQuery ();

6.10. Kombinácia dotazov

Hibernate Search nakoniec podporuje aj kombinovanie dotazov pomocou rôznych stratégií:

  • MALI BY: dopyt by mal obsahovať zodpovedajúce prvky poddotazu
  • MUSIEŤ: dopyt musí obsahovať zodpovedajúce prvky poddotazu
  • NESMIEŠ: dopyt nesmie obsahovať zodpovedajúce prvky poddotazu

Agregácie sú podobné boolovským AND, OR a NIE. Názvy sa však odlišujú, aby sa zdôraznilo, že majú vplyv aj na relevantnosť.

Napríklad a MAL by medzi dvoma dopytmi je podobný boolean ALEBO: ak má jeden z dvoch dotazov zhodu, táto zhoda sa vráti.

Ak sa však oba dotazy zhodujú, bude mať zhoda vyššiu relevanciu v porovnaní s prípadom, keď sa zhoduje iba jeden dopyt:

Dotaz combinedQuery = queryBuilder .bool () .must (queryBuilder.keyword () .onField ("productName"). Matching ("apple") .createQuery ()) .must (queryBuilder.range () .onField ("pamäť") .z (64) .to (256) .createQuery ()) .by (queryBuilder.phrase () .onField ("description"). vety ("face id") .createQuery ()) .must (queryBuilder.keyword ( ) .onField ("productName"). matching ("samsung") .createQuery ()) .not () .createQuery ();

7. Záver

V tomto článku sme diskutovali o základoch Hibernate Search a ukázali, ako implementovať najdôležitejšie typy dotazov. Pokročilejšie témy nájdete v oficiálnej dokumentácii.

Celý zdrojový kód príkladov je ako vždy k dispozícii na serveri GitHub.


$config[zx-auto] not found$config[zx-overlay] not found