-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…-and-simple-crud [FEAT] 엘라스틱서치 기본 설정 및 사진 저장, 조희 repository 구현
- Loading branch information
Showing
16 changed files
with
437 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/FaceVector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.document; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.elasticsearch.annotations.Document; | ||
import org.springframework.data.elasticsearch.annotations.Field; | ||
import org.springframework.data.elasticsearch.annotations.FieldType; | ||
|
||
import java.util.List; | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Document(indexName = "face_vectors") | ||
public class FaceVector { | ||
@Id | ||
private String id; | ||
@Field(type = FieldType.Long) | ||
private String shareGroupId; | ||
@Field(type = FieldType.Keyword) | ||
private String keyValue; | ||
@Field(type = FieldType.Date) | ||
private String date; | ||
@Field(type = FieldType.Dense_Vector) | ||
private List<Float> faceVector; | ||
} |
32 changes: 32 additions & 0 deletions
32
src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/PhotoEs.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.document; | ||
|
||
import lombok.*; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.elasticsearch.annotations.Document; | ||
import org.springframework.data.elasticsearch.annotations.Field; | ||
import org.springframework.data.elasticsearch.annotations.FieldType; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Document(indexName = "photos_es") | ||
public class PhotoEs { | ||
@Id | ||
private String id; | ||
@Field(type = FieldType.Long) | ||
private Long shareGroupId; | ||
@Field(type = FieldType.Keyword) | ||
private String url; | ||
@Field(type = FieldType.Keyword) | ||
private String name; | ||
@Field(type = FieldType.Date) | ||
private String createdAt; | ||
@Field(type = FieldType.Long) | ||
private List<Long> faceTag; | ||
@Field(type = FieldType.Long) | ||
private List<Long> downloadTag; | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/SampleFaceVector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.document; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.elasticsearch.annotations.Document; | ||
import org.springframework.data.elasticsearch.annotations.Field; | ||
import org.springframework.data.elasticsearch.annotations.FieldType; | ||
|
||
import java.util.List; | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Document(indexName = "sample_face_vectors") | ||
public class SampleFaceVector { | ||
@Id | ||
private String id; | ||
@Field(type = FieldType.Long) | ||
private Long memberId; | ||
@Field(type = FieldType.Dense_Vector) | ||
private List<Float> faceVector; | ||
} |
32 changes: 32 additions & 0 deletions
32
src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/face_vectors.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"settings" : { | ||
"index" :{ | ||
"number_of_shards" : 5, | ||
"number_of_replicas" : 1 | ||
} | ||
}, | ||
"mappings" : { | ||
"dynamic": "false", | ||
"_routing": { | ||
"required" : true | ||
}, | ||
"properties" : { | ||
"shareGroupId" : { | ||
"type" : "long" | ||
}, | ||
"keyValue" : { | ||
"type" : "keyword" | ||
}, | ||
"createdAt" : { | ||
"type" : "date", | ||
"format": "yyyy-MM-dd HH:mm:ss" | ||
}, | ||
"faceVector" : { | ||
"type": "dense_vector", | ||
"dims": 128, | ||
"index": true, | ||
"similarity" : "dot_product" | ||
} | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/photos_es.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
|
||
{ | ||
"settings" : { | ||
"index" :{ | ||
"number_of_shards" : 2, | ||
"number_of_replicas" : 2 | ||
} | ||
}, | ||
"mappings" : { | ||
"dynamic": "false", | ||
"_routing": { | ||
"required" : true | ||
}, | ||
"properties" : { | ||
"shareGroupId" : { | ||
"type" : "long" | ||
}, | ||
"url" : { | ||
"type" : "keyword" | ||
}, | ||
"name" : { | ||
"type" : "keyword" | ||
}, | ||
"createdAt" : { | ||
"type" : "date", | ||
"format": "yyyy-MM-dd HH:mm:ss" | ||
}, | ||
"faceTag" : { | ||
"type" : "long" | ||
}, | ||
"downloadTag" : { | ||
"type" : "long" | ||
} | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/sample_photo_vectors.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"settings" : { | ||
"index" :{ | ||
"number_of_shards" : 3, | ||
"number_of_replicas" : 1 | ||
} | ||
}, | ||
"mappings" : { | ||
"dynamic": "false", | ||
"properties" : { | ||
"memberId" : { | ||
"type" : "long" | ||
}, | ||
"faceVector" : { | ||
"type": "dense_vector", | ||
"dims": 128, | ||
"index": true, | ||
"similarity" : "dot_product" | ||
} | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/FaceVectorRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.repository; | ||
|
||
import com.umc.naoman.domain.photo.elasticsearch.document.FaceVector; | ||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface FaceVectorRepository extends ElasticsearchRepository<FaceVector,String> { | ||
} |
172 changes: 172 additions & 0 deletions
172
...in/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsClientRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.repository; | ||
|
||
import co.elastic.clients.elasticsearch.ElasticsearchClient; | ||
import co.elastic.clients.elasticsearch.core.BulkRequest; | ||
import co.elastic.clients.elasticsearch.core.BulkResponse; | ||
import co.elastic.clients.elasticsearch.core.SearchResponse; | ||
import co.elastic.clients.elasticsearch.core.search.Hit; | ||
import com.umc.naoman.domain.photo.elasticsearch.document.PhotoEs; | ||
import com.umc.naoman.global.error.BusinessException; | ||
import com.umc.naoman.global.error.code.ElasticsearchErrorCode; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.PageImpl; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.io.IOException; | ||
import java.time.LocalDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@Repository | ||
@RequiredArgsConstructor | ||
public class PhotoEsClientRepository { | ||
private final ElasticsearchClient elasticsearchClient; | ||
|
||
//사진 업로드 시 ES에 벌크로 업로드 | ||
public void savePhotoBulk(List<String> url, List<String> nameList, Long shareGroupId) { | ||
List<PhotoEs> photoEsList = new ArrayList<>(); | ||
for(int i=0; i<url.size(); i++){ | ||
PhotoEs photoEs = PhotoEs.builder() | ||
.shareGroupId(shareGroupId) | ||
.url(url.get(i)) | ||
.name(nameList.get(i)) | ||
.createdAt(esTimeFormat(LocalDateTime.now())) | ||
.build(); | ||
photoEsList.add(photoEs); | ||
} | ||
BulkRequest.Builder bulkBuilder = new BulkRequest.Builder(); | ||
for(PhotoEs photoEs :photoEsList){ | ||
bulkBuilder.operations(op ->op | ||
.index(idx -> idx | ||
.index("photos_es") | ||
.routing(shareGroupId.toString()) | ||
.document(photoEs) | ||
) | ||
); | ||
} | ||
try { | ||
BulkResponse result = elasticsearchClient.bulk(bulkBuilder.build()); | ||
} catch (IOException e) { | ||
throw new BusinessException(ElasticsearchErrorCode.ELASTICSEARCH_IOEXCEPTION, e); | ||
} | ||
} | ||
|
||
//특정 공유 그룹의 모든 사진 검색 | ||
public Page<PhotoEs> findPhotoEsByShareGroupId(Long shareGroupId, Pageable pageable) { | ||
SearchResponse<PhotoEs> response = null; | ||
|
||
pageable.getPageNumber(); | ||
try{ | ||
response = elasticsearchClient.search(s->s | ||
.index("photos_es") | ||
.routing(shareGroupId.toString()) | ||
.from(getFrom(pageable)) | ||
.size(pageable.getPageSize()) | ||
.sort(sort -> sort | ||
.field(f -> f | ||
.field("createdAt"))) | ||
.query(q->q | ||
.term(t->t | ||
.field("shareGroupId") | ||
.value(shareGroupId) | ||
) | ||
), | ||
PhotoEs.class | ||
); | ||
} catch (IOException e) { | ||
throw new BusinessException(ElasticsearchErrorCode.ELASTICSEARCH_IOEXCEPTION, e); | ||
} | ||
return toPagePhotoEs(response.hits().hits(), pageable); | ||
} | ||
|
||
//특정 공유 그룹의 얼굴이 태그된 사진 검색 | ||
public Page<PhotoEs> findPhotoEsByShareGroupIdAndFaceTag(Long shareGroupId,Long faceTag, Pageable pageable) throws IOException{ | ||
SearchResponse<PhotoEs> response = null; | ||
try{ | ||
response = elasticsearchClient.search(s->s | ||
.index("photos_es") | ||
.routing(shareGroupId.toString()) | ||
.from(getFrom(pageable)) | ||
.size(pageable.getPageSize()) | ||
.sort(sort -> sort | ||
.field(f -> f | ||
.field("createdAt"))) | ||
.query(q->q | ||
.bool(b->b | ||
.must(m->m | ||
.term(t->t | ||
.field("shareGroupId") | ||
.value(shareGroupId) | ||
) | ||
) | ||
.must(m->m | ||
.term(t->t | ||
.field("faceTag") | ||
.value(faceTag) | ||
) | ||
) | ||
) | ||
), | ||
PhotoEs.class | ||
); | ||
} catch (IOException e) { | ||
throw new BusinessException(ElasticsearchErrorCode.ELASTICSEARCH_IOEXCEPTION, e); | ||
} | ||
|
||
return toPagePhotoEs(response.hits().hits(), pageable); | ||
} | ||
|
||
//특정 공유 그룹의 얼굴이 태그되지 않은 사진 검색 | ||
public Page<PhotoEs> findPhotoEsByShareGroupIdAndNotFaceTag(Long shareGroupId, Pageable pageable){ | ||
SearchResponse<PhotoEs> response = null; | ||
try{ | ||
response = elasticsearchClient.search(s->s | ||
.index("photos_es") | ||
.routing(shareGroupId.toString()) | ||
.from(getFrom(pageable)) | ||
.size(pageable.getPageSize()) | ||
.sort(sort -> sort | ||
.field(f -> f | ||
.field("createdAt"))) | ||
.query(q->q | ||
.bool(b -> b | ||
.must(m -> m | ||
.term(t -> t | ||
.field("shareGroupId") | ||
.value(shareGroupId) | ||
) | ||
) | ||
.mustNot(mn -> mn | ||
.exists(e -> e | ||
.field("faceTag") | ||
) | ||
) | ||
) | ||
), | ||
PhotoEs.class | ||
); | ||
}catch (IOException e){ | ||
throw new BusinessException(ElasticsearchErrorCode.ELASTICSEARCH_IOEXCEPTION, e); | ||
} | ||
|
||
return toPagePhotoEs(response.hits().hits(), pageable); | ||
} | ||
|
||
String esTimeFormat(LocalDateTime localDateTime){ | ||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | ||
return localDateTime.format(dateTimeFormatter); | ||
} | ||
|
||
private Page<PhotoEs> toPagePhotoEs(List<Hit<PhotoEs>> hits, Pageable pageable){ | ||
List<PhotoEs> photoEsList = hits.stream().map(Hit::source).collect(Collectors.toList()); | ||
return new PageImpl<>(photoEsList, pageable, hits.size()); | ||
} | ||
|
||
private int getFrom(Pageable pageable){ | ||
return pageable.getPageNumber() * pageable.getPageSize(); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.repository; | ||
|
||
import com.umc.naoman.domain.photo.elasticsearch.document.PhotoEs; | ||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface PhotoEsRepository extends ElasticsearchRepository<PhotoEs, String> { | ||
} |
9 changes: 9 additions & 0 deletions
9
...java/com/umc/naoman/domain/photo/elasticsearch/repository/SampleFaceVectorRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.umc.naoman.domain.photo.elasticsearch.repository; | ||
|
||
import com.umc.naoman.domain.photo.elasticsearch.document.SampleFaceVector; | ||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface SampleFaceVectorRepository extends ElasticsearchRepository<SampleFaceVector,String> { | ||
} |
Oops, something went wrong.