読者です 読者をやめる 読者になる 読者になる

修行@ホーチミン

ホーチミン長期出張の日記です

SpringBoot Elasticsearch 接続

前書き

SpringBootとElasticsearchの接続まではできたのでメモ書き。

オートコンプリートで使おうと思ったのですが、思ったような使い方ができないので

明日粘ってだめだったら戻します..。

 

準備

MySQLからElasticsearchにembulkを使ってデータを投入。

embulkダウンロード

curl --create-dirs -o ~/.embulk/bin/embulk -L "http://dl.embulk.org/embulk-latest.jar"
chmod +x ~/.embulk/bin/embulk
echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

プラグインのinstall

embulk gem install embulk-input-mysql embulk-output-elasticsearch 

config作成

in:
  type: mysql
  user: user
  password: pass
  database: sample_db
  table: hotel
  host: localhost
  select : "id,name,address,country_code,city_code,grade,facility"
  where : "delete_flag=0"
out:
  type: elasticsearch
  index: hotel_auto_complete
  index_type: hotel_auto_complete
  nodes:
  - {host: localhost, port: 9300}

データ投入

# 投入データの確認
embulk preview config.yml

# 投入
embulk run config.yml 

 

SpringBootで使ったもの

 

設定ファイル

接続用に下記をapplication.ymlに追記

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: localhost:9300

Repository

public interface AutoCompleteRepository extends ElasticsearchRepository<AutoComplete, Long> {
    
    //@Query("{\"query\": {\"prefix\": {\"address\": \"?0\"}}}")
    public List<AutoComplete> findByNameLike(String query, Pageable pageable);

}

Entity

@Document(indexName = "hotel_auto_complete", type = "hotel_auto_complete")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class AutoComplete {

    @Id
    private Long id;

    private String name;

    private String address;

    private String countryCode;
    
    private String cityCode;

    private Integer grade;

    private String facility;
    
    private String imagePath;
}

Service

@Service
@Transactional
public class AutoCompleteService {
    
    

    @Autowired
    private AutoCompleteRepository autoCompleteRepository;

    /**
     * 
     * @return
     */
    public HotelAutoCompleteResponseBody autoComplete(AutoCompleteRequest request) {
        
        Pageable topTen = new PageRequest(0, 10);
        
        List<String> resultList = autoCompleteRepository.findByNameLike(request.getQuery(), topTen).stream()
                .map(x -> new String(x.getName())).collect(MoreCollectors.toImmutableList());
        
        return new HotelAutoCompleteResponseBody(resultList);
        
        
        
    }
}

 

感想

Springに備わっているメソッドを、いくつか試しに使ったのですが

  • findByNameLike
    • Like文のような使い方ができますが空白スペースが入ると検索結果0になる。
  • findByNameContaining
    • "ABC DEF"みたいな文字列だと"ABC"まで入れないと返却がない。
  • @Query
    • 引数を使った素敵なQueryが書けず..。
  • ElasticsearchのSuggester
    • Springでの使い方が記述されたサイトが少なく断念 ← いまここ

 

このレベルの使い方だと、DB直接クエリ投げたほうがいい感じという...。

無能感...