- Getting Started with Hazelcast
- Mat Johns
- 630字
- 2021-08-06 16:56:52
Searching and indexing
In moving towards creating clean key/value-based storage, we may find that we have lost some of the extra searching capabilities that traditional databases offer. Mainly that we now can't find records within a dataset without knowing the primary key to that entry. However, fear not, as Hazelcast provides similar capabilities for searching its maps by predefined indexes. These can be either ordered (ascending) or unordered, depending on our particular data needs. But be aware that indexing doesn't come for free; the internal lookup table used to provide the quick searching on reads is maintained as we make changes to the map; this will add latency to every write operation to that namespace.
So firstly, let's create a new plain old Java object (POJO) to represent a city.
import java.io.Serializable; public class City implements Serializable { private String name; private String country; private int population; public City(String name, String country, int population) { this.name = name; this.country = country; this.population = population; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; City other = (City) o; if (!this.country.equals(other.country)) return false; if (!this.name.equals(other.name)) return false; return true; } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + country.hashCode(); return result; } @Override public String toString() { return String.format( "City{name='%s', country='%s', population=%d}", name, country, population); } }
As you can see, we have created our City
class to implement Serializable
so that it can be correctly persisted within Hazelcast. We have also implemented the equals()
and hashCode()
methods so the required behavior is ensured. Additionally, a toString()
method has been added for debugging convenience.
Using this, we can update our previous map example to use our new city POJO. One major change from the previous example is that in order to access the additional indexing functionally, we have to use the Hazelcast specific IMap
interface rather than the standard Java Map
that we used before.
In order to search the map, we need to provide a Predicate
object to filter on. One such implementation of this is that we can use SqlPredicate
, which provides us with the ability to use a SQL-like syntax to describe the filter.
IMap<String, City> capitals = hz.getMap("capitals"); capitals.addIndex("name", false); capitals.addIndex("population", true); capitals.put("GB", new City("London", "GB", 8174100)); capitals.put("FR", new City("Paris", "FR", 2268265)); capitals.put("US", new City("Washington DC", "US", 601723)); capitals.put("AU", new City("Canberra", "AU", 354644)); Collection<City> possibleLondons = capitals.values( new SqlPredicate("name = 'London'"));); System.err.println(possibleLondons); Collection<City> largeCities = capitals.values( new SqlPredicate("population > 1000000")); System.err.println(largeCities);
The supported syntax is very much a limited subset of SQL, but should feel familiar.
- AND/OR: For combining multiple expressions
- =, !=, <, <=, >, >=: For expression comparison
- LIKE: For simple string pattern matching expressions
- IN: For providing a defined list of sought values
- BETWEEN: For providing a range of sought numeric values
- NOT: Can be used as a prefix to negate the expression
The preceding functions are used in the following code:
country = 'GB' AND population BETWEEN 10000 AND 100000 country NOT IN ('GB', 'FR') name LIKE 'L%'
If you would prefer to construct your query more programmatically, we can use a JPA-like criteria API provided by PredicateBuilder
, or more manually using various helper methods in Predicates
. We could use the following alternative code in place of our previous SQL based predicates:
EntryObject c = new PredicateBuilder().getEntryObject(); Predicate londonPredicate = c.get("name").equal("London"); Collection<City> possibleLondons = capitals.values(londonPredicate); System.err.println(possibleLondons); Predicate largeCityPredicate = Predicates.greaterThan( Predicates.get("population"), 1000000); Collection<City> largeCities = capitals.values(largeCityPredicate); System.err.println(largeCities);
- Java Web開發(fā)學習手冊
- Django+Vue.js商城項目實戰(zhàn)
- 垃圾回收的算法與實現(xiàn)
- 編寫整潔的Python代碼(第2版)
- 樂高機器人設計技巧:EV3結構設計與編程指導
- R語言數(shù)據(jù)可視化實戰(zhàn)
- 蘋果的產(chǎn)品設計之道:創(chuàng)建優(yōu)秀產(chǎn)品、服務和用戶體驗的七個原則
- Microsoft Dynamics AX 2012 R3 Financial Management
- Mastering ArcGIS Enterprise Administration
- Windows Phone 8 Game Development
- Ionic3與CodePush初探:支持跨平臺與熱更新的App開發(fā)技術
- Slick2D Game Development
- jBPM6 Developer Guide
- Neo4j High Performance
- Python數(shù)據(jù)科學實戰(zhàn)