Luceneで登録・更新・削除のサンプルを作成してみた



正直苦戦した(;´∀`)

最新の4.2、4.3で動作確認済みだぜぇ(゚∀゚)


てか日本語サイト少なすぎだわ(´;ω;`)


なんで米googleを使って検索しないといけないんだよ٩(๑`^´๑)۶



もぉ少しで激おこスティックファイナリアリティぷんぷんドリームだったゎヾ(*`Д´*)ノ"




import java.io.File;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.ja.JapaneseAnalyzer;
import org.apache.lucene.analysis.ja.JapaneseTokenizer.Mode;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;


/**
 * Luceneユーティリティ
 */
public final class LuceneUtil {

 /** */
 private LuceneUtil() { }

 /** 全文検索用日本語アナライザー */
 // Version.LUCENE_43 Luceneバージョン
 // null UserDictionary ユーザ辞書
 // Mode.SEARCH   モード(NORMAL、SEARCH、EXTENDED) ※デフォルトはNORMAL
 // DefaultStopSet   ストップワード「の」「に」「は」「を」「と」など
 // DefaultStopTags   ストップタグ[接続詞][助動詞][記号]など
 public static final Analyzer ANALYZER = new JapaneseAnalyzer(
   Version.LUCENE_43, null, Mode.SEARCH, JapaneseAnalyzer.getDefaultStopSet(), JapaneseAnalyzer.getDefaultStopTags());

 /** Key */
 // 主キー項目(あると便利w)
 public static final String INDEX_KEY = "key";

 /** Code */
 // コード
 public static final String INDEX_CODE = "code";

 /** Value */
 // 値
 public static final String INDEX_VALUE = "value";
 
 /** インデックスパス */
 // インデックスの保存場所 今回は ドライブ/index/ に配置
 public static final String INDEX_PATH = "/index/";
 
 /**
  * インデックスの登録
  * @param key キー
  * @param code コード
  * @param value 値
  * @throws Exception システム例外
  */
 public static void regIndex(final Long key, final String code, final String value) throws Exception {
  
  /**
   * ドキュメントの取得
   */
  Document doc = new Document();

  // key
  doc.add(new Field(INDEX_KEY, key.toString(), notAnalyzedFieldType()));

  // code
  doc.add(new Field(INDEX_CODE, code, notAnalyzedFieldType()));

  // value
  doc.add(new Field(INDEX_VALUE, value, analyzedFieldType()));

  /**
   * 保存処理
   */
  try (Directory directory = FSDirectory.open(new File(INDEX_PATH));
    IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_43, ANALYZER))) {

   // DocumentをIndexに保存
   writer.addDocument(doc);
   writer.commit();
  }
 }
 
 /**
  * インデックスの更新
  * @param key キー
  * @param value 値
  * @throws Exception システム例外
  */
  public static void updIndex(final Long key, final String value) throws Exception {

  /**
   * インデックスの検索
   */
  // key = 引数.key
  Term term = new Term(INDEX_KEY, key.toString());

  // 検索
  IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(INDEX_PATH))));
  // 1件検索
  ScoreDoc[] hits = searcher.search(new TermQuery(term), null, 1).scoreDocs;

  /**
   * Luceneの設定
   */
  try (Directory directory = FSDirectory.open(new File(INDEX_PATH));
    IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_43, ANALYZER))) {

   /**
    * ドキュメントの取得
    */
   Document doc = searcher.doc(hits[0].doc);

   /**
    * valueの更新
    */
   // valueの削除
   doc.removeField(INDEX_VALUE);
   // valueの再設定
   doc.add(new Field(INDEX_VALUE, value, analyzedFieldType()));

   /**
    * 上書き
    */
   writer.updateDocument(term, doc);
   writer.commit();
  }
 }
 
 /**
  * インデックスの更新
  * @param code コード
  * @param value 値
  * @throws Exception システム例外
  */
  public static void updIndex(final String code, final String value) throws Exception {

  /**
   * インデックスの検索
   */
  // key = 引数.key
  Term term = new Term(INDEX_CODE, code);

  // 検索
  IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(INDEX_PATH))));
  // 何件ヒットするかわからないので Integer.MAX_VALUE
  ScoreDoc[] hits = searcher.search(new TermQuery(term), null, Integer.MAX_VALUE).scoreDocs;

  /**
   * Luceneの設定
   */
  try (Directory directory = FSDirectory.open(new File(INDEX_PATH));
    IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_43, ANALYZER))) {

   for (ScoreDoc hit : hits) {

    /**
     * ドキュメントの取得
     */
    Document doc = searcher.doc(hit.doc);
    
    /**
     * valueの更新
     */
    // valueの削除
    doc.removeField(INDEX_VALUE);
    // valueの再設定
    doc.add(new Field(INDEX_VALUE, value, analyzedFieldType()));

    /**
     * 上書き
     */
    writer.updateDocument(term, doc);

   }
   
   // コミット
   writer.commit();
  }
 }

  /**
  * インデックスの削除
  * @param key キー
  * @throws Exception システム例外
  */
 public static void delIndex(final Long key) throws Exception {

  /**
   * Luceneの設定
   */
  try (Directory directory = FSDirectory.open(new File(INDEX_PATH));
    IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_43, ANALYZER))) {

   // key = 引数.key
   Term term = new Term(INDEX_KEY, key.toString());

   /**
    * インデックスの削除処理
    */
   writer.deleteDocuments(new TermQuery(term));

   writer.commit();
  }
 }

 
 /**
  * Index.ANALYZEDの設定
  * @return FieldType
  */
 private static final FieldType analyzedFieldType() {
  FieldType ft = new FieldType();
  ft.setStored(true);
  ft.setIndexed(true);
  ft.setTokenized(true);
  ft.setStoreTermVectors(true);
  ft.setOmitNorms(true);
  ft.freeze();
  return ft;
 }

 /**
  * Index.NOT_ANALYZEDの設定
  * @return FieldType
  */
 private static final FieldType notAnalyzedFieldType() {
  FieldType ft = new FieldType();
  ft.setStored(true);
  ft.setIndexed(true);
  ft.setTokenized(false);
  ft.setStoreTermVectors(true);
  ft.setOmitNorms(true);
  ft.freeze();
  return ft;
 }
 } 





昔3.0を使ってたが、いくつか非推奨になってて焦ったぜ(´;ω;`)

0 件のコメント:

コメントを投稿