roms-documents.zip
), which is an archive of a web application that is configured with your choices.<dependency>
<groupId>com.redis.om</groupId>
<artifactId>redis-om-spring</artifactId>
<version>0.5.2-SNAPSHOT</version>
</dependency>
dependencies {
implementation 'com.redis.om.spring:redis-om-spring:0.1.0-SNAPSHOT'
}
package com.redis.om;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RomsDocumentsApplication {
public static void main(String[] args) {
SpringApplication.run(RomsDocumentsApplication.class, args);
}
}
package com.redis.om;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.redis.om.spring.annotations.EnableRedisDocumentRepositories;
@SpringBootApplication
@EnableRedisDocumentRepositories(basePackages = "com.redis.om.documents.*")
public class RomsDocumentsApplication {
public static void main(String[] args) {
SpringApplication.run(RomsDocumentsApplication.class, args);
}
}
version: '3.9'
services:
redis:
image: 'redis/redis-stack:latest'
ports:
- '6379:6379'
volumes:
- ./data:/data
environment:
- REDIS_ARGS: --save 20 1
deploy:
replicas: 1
restart_policy:
condition: on-failure
docker compose up
redis-cli MONITOR
package com.redis.om.documents.domain;
import java.util.HashSet;
import java.util.Set;
import org.springframework.data.annotation.Id;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.index.Indexed;
import com.redis.om.spring.annotations.Document;
import com.redis.om.spring.annotations.Searchable;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Document
public class Company {
@Id
private String id;
@NonNull
@Searchable
private String name;
@Indexed
private Set<String> tags = new HashSet<String>();
@NonNull
private String url;
@NonNull
@Indexed
private Point location;
@NonNull
@Indexed
private Integer numberOfEmployees;
@NonNull
@Indexed
private Integer yearFounded;
private boolean publiclyListed;
}
package com.redis.om.documents.repositories;
import com.redis.om.documents.domain.Company;
import com.redis.om.spring.repository.RedisDocumentRepository;
public interface CompanyRepository extends RedisDocumentRepository<Company, String> {
}
deleteAll
method to clear the database (be careful with this is production! 🙀)Company
instances; one for Redis and one for Microsoft. Including name, URL, Geo Location, number
of employees, year established, as well a set of tags.save
method passing each of the created POJOs.package com.redis.om.documents;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.geo.Point;
import com.redis.om.documents.domain.Company;
import com.redis.om.documents.repositories.CompanyRepository;
import com.redis.om.spring.annotations.EnableRedisDocumentRepositories;
@SpringBootApplication
@Configuration
@EnableRedisDocumentRepositories(basePackages = "com.redis.om.documents.*")
public class RomsDocumentsApplication {
@Autowired
CompanyRepository companyRepo;
@Bean
CommandLineRunner loadTestData() {
return args -> {
companyRepo.deleteAll();
Company redis = Company.of("Redis", "https://redis.com", new Point(-122.066540, 37.377690), 526, 2011);
redis.setTags(Set.of("fast", "scalable", "reliable"));
Company microsoft = Company.of("Microsoft", "https://microsoft.com", new Point(-122.124500, 47.640160), 182268, 1975);
microsoft.setTags(Set.of("innovative", "reliable"));
companyRepo.save(redis);
companyRepo.save(microsoft);
};
}
public static void main(String[] args) {
SpringApplication.run(RomsDocumentsApplication.class, args);
}
}
./mvnw spring-boot:run
[INFO] --- spring-boot-maven-plugin:2.6.0-M1:run (default-cli) @ roms-documents ---
[INFO] Attaching agents: []
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.0-M1)
2021-11-30 09:45:58.094 INFO 36380 --- [ restartedMain] c.r.o.d.RomsDocumentsApplication : Starting RomsDocumentsApplication using Java 11.0.9 on BSB.lan with PID 36380 (/Users/bsb/Code/module-clients/java/high-level/redis-om/redis-om-spring/demos/roms-documents/target/classes started by briansam-bodden in /Users/bsb/Code/module-clients/java/high-level/redis-om/redis-om-spring/demos/roms-documents)
1638291270.881079 [0 172.19.0.1:63378] "FT.CREATE" "CompanyIdx" "ON" "JSON" "PREFIX" "1" "com.redis.om.documents.domain.Company:" "SCHEMA" "$.name" "AS" "name" "TEXT" "$.tags[*]" "AS" "tags" "TAG" "$.location" "AS" "location" "GEO" "$.numberOfEmployees" "AS" "numberOfEmployees" "NUMERIC" "$.yearFounded" "AS" "yearFounded" "NUMERIC"
1638291270.936493 [0 172.19.0.1:63378] "DEL" "com.redis.om.documents.domain.Company"
1638291270.958384 [0 172.19.0.1:63378] "SISMEMBER" "com.redis.om.documents.domain.Company" "01FNRW9V98CYQMV2YAB7M4KFGQ"
1638291270.966868 [0 172.19.0.1:63378] "JSON.SET" "com.redis.om.documents.domain.Company:01FNRW9V98CYQMV2YAB7M4KFGQ" "." "{\"id\":\"01FNRW9V98CYQMV2YAB7M4KFGQ\",\"name\":\"Redis\",\"tags\":[\"reliable\",\"fast\",\"scalable\"],\"url\":\"https://redis.com\",\"location\":\"-122.06654,37.37769\",\"numberOfEmployees\":526,\"yearFounded\":2011,\"publiclyListed\":false}"
1638291270.970030 [0 172.19.0.1:63378] "SADD" "com.redis.om.documents.domain.Company" "01FNRW9V98CYQMV2YAB7M4KFGQ"
127.0.0.1:6379> SCAN 0 MATCH com.redis.om.documents.domain.Company*
1) "0"
2) 1) "com.redis.om.documents.domain.Company:01FNRW9V98CYQMV2YAB7M4KFGQ"
2) "com.redis.om.documents.domain.Company:01FNRW9V9VFNG0MQCJDXZPEG3H"
3) "com.redis.om.documents.domain.Company"
127.0.0.1:6379> TYPE "com.redis.om.documents.domain.Company"
set
127.0.0.1:6379> SMEMBERS "com.redis.om.documents.domain.Company"
1) "01FNRW9V9VFNG0MQCJDXZPEG3H"
2) "01FNRW9V98CYQMV2YAB7M4KFGQ"
127.0.0.1:6379> TYPE "com.redis.om.documents.domain.Company:01FNRW9V98CYQMV2YAB7M4KFGQ"
ReJSON-RL
127.0.0.1:6379> JSON.GET "com.redis.om.documents.domain.Company:01FNRW9V98CYQMV2YAB7M4KFGQ"
"{\"id\":\"01FNRW9V98CYQMV2YAB7M4KFGQ\",\"name\":\"Redis\",\"tags\":[\"reliable\",\"fast\",\"scalable\"],\"url\":\"https://redis.com\",\"location\":\"-122.06654,37.37769\",\"numberOfEmployees\":526,\"yearFounded\":2011,\"publiclyListed\":false}"
package com.redis.om.documents.repositories;
import java.util.Optional;
// ... other imports ommitted ...
public interface CompanyRepository extends RedisDocumentRepository<Company, String> {
// find one by property
Optional<Company> findOneByName(String name);
}
package com.redis.om.documents.controllers;
import java.util.Optional;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.redis.om.documents.domain.Company;
import com.redis.om.documents.repositories.CompanyRepository;
@RestController
@RequestMapping("/api/companies")
public class CompanyController {
@Autowired
CompanyRepository repository;
@GetMapping("name/{name}")
Optional<Company> byName(@PathVariable("name") String name) {
return repository.findOneByName(name);
}
}
➜ curl --location --request GET 'http://localhost:8080/api/companies/name/Redis'
{"id":"01FNRW9V98CYQMV2YAB7M4KFGQ","name":"Redis","tags":["reliable","fast","scalable"],"url":"https://redis.com","location":{"x":-122.06654,"y":37.37769},"numberOfEmployees":526,"yearFounded":2011,"publiclyListed":false}
{
"id": "01FNRW9V98CYQMV2YAB7M4KFGQ",
"name": "Redis",
"tags": ["reliable", "fast", "scalable"],
"url": "https://redis.com",
"location": {
"x": -122.06654,
"y": 37.37769
},
"numberOfEmployees": 526,
"yearFounded": 2011,
"publiclyListed": false
}
1638344903.218982 [0 172.19.0.1:63410] "FT.SEARCH" "CompanyIdx" "@name:Redis "
// geospatial query
Iterable<Company> findByLocationNear(Point point, Distance distance);
@GetMapping("near")
Iterable<Company> byLocationNear(//
@RequestParam("lat") double lat, //
@RequestParam("lon") double lon, //
@RequestParam("d") double distance) {
return repository.findByLocationNear(new Point(lon, lat), new Distance(distance, Metrics.MILES));
}
➜ curl --location --request GET 'http://localhost:8080/api/companies/near?lat=37.384&lon=-122.064&d=30'
[{"id":"01FNRW9V98CYQMV2YAB7M4KFGQ","name":"Redis","tags":["reliable","fast","scalable"],"url":"https://redis.com","location":{"x":-122.06654,"y":37.37769},"numberOfEmployees":526,"yearFounded":2011,"publiclyListed":false}]
[
{
"id": "01FNRW9V98CYQMV2YAB7M4KFGQ",
"name": "Redis",
"tags": ["reliable", "fast", "scalable"],
"url": "https://redis.com",
"location": {
"x": -122.06654,
"y": 37.37769
},
"numberOfEmployees": 526,
"yearFounded": 2011,
"publiclyListed": false
}
]
1638344951.451871 [0 172.19.0.1:63410] "FT.SEARCH" "CompanyIdx" "@location:[-122.064 37.384 30.0 mi] "
// find by tag field, using JRediSearch "native" annotation
@Query("@tags:{$tags}")
Iterable<Company> findByTags(@Param("tags") Set<String> tags);
➜ curl --location --request GET 'http://localhost:8080/api/companies/tags?tags=reliable'
[{"id":"01FNTF7QKAGCQYMWWBV3044DHW","name":"Redis","tags":["reliable","fast","scalable"],"url":"https://redis.com","location":{"x":-122.06654,"y":37.37769},"numberOfEmployees":526,"yearFounded":2011,"publiclyListed":false},{"id":"01FNTF7QKXJ1CNZERHADN91YBR","name":"Microsoft","tags":["reliable","innovative"],"url":"https://microsoft.com","location":{"x":-122.1245,"y":47.64016},"numberOfEmployees":182268,"yearFounded":1975,"publiclyListed":false}]
[
{
"id": "01FNTF7QKAGCQYMWWBV3044DHW",
"name": "Redis",
"tags": ["reliable", "fast", "scalable"],
"url": "https://redis.com",
"location": {
"x": -122.06654,
"y": 37.37769
},
"numberOfEmployees": 526,
"yearFounded": 2011,
"publiclyListed": false
},
{
"id": "01FNTF7QKXJ1CNZERHADN91YBR",
"name": "Microsoft",
"tags": ["reliable", "innovative"],
"url": "https://microsoft.com",
"location": {
"x": -122.1245,
"y": 47.64016
},
"numberOfEmployees": 182268,
"yearFounded": 1975,
"publiclyListed": false
}
]
1638345120.384300 [0 172.19.0.1:63412] "FT.SEARCH" "CompanyIdx" "@tags:{reliable} "
// find by numeric property
Iterable<Company> findByNumberOfEmployees(int noe);
// find by numeric property range
Iterable<Company> findByNumberOfEmployeesBetween(int noeGT, int noeLT);
// starting with/ending with
Iterable<Company> findByNameStartingWith(String prefix);