2012-03-21 10 views
1

私は、音楽アーティスト/トラック情報の大きなコーパスへの検索フロントエンドとしてSolrを使用しています。Solr/Lucene:「ワード数」を数値に変換するフィルタ

Lucene/Solrのインデックス時に「5」のような「ワード数」を同等の数値(「5」)に変換するフィルターや他の方法はありますか?

例として、「Ben Folds Five」を検索すると「Ben Folds 5」が返されます。

PatternReplaceFilterFactoryがありますが、正規表現内のすべてが過剰なもののようです。ここで

+2

あなたは同義語を使用することをお勧めします。これは、インデックス時、クエリ時、またはその両方で実行できます。 –

+2

シノニムアナライザーでインデックス時に実行します。私はそれがsolrにマップされているかどうかはわかりませんが、誰かが知っています。 – Reactormonk

+0

@Tassヒントをお寄せいただきありがとうございます。私は[SynonymFilter](http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.SynonymFilterFactory)を調べましたが、明示的なマッピングを持つテキストファイルが必要と思われます。すべての可能な番号に対して扱いにくいでしょう。何か不足していますか? – Spoom

答えて

1

は(私は過去にそれを使用して)動作するコードです:

hereから撮影
import java.util.*; 

class ConvertWordToNumber { 

    public static String WithSeparator(long number) { 
     if (number < 0) { 
      return "-" + WithSeparator(-number); 
     } 
     if (number/1000L > 0) { 
      return WithSeparator(number/1000L) + "," 
        + String.format("%1$03d", number % 1000L); 
     } else { 
      return String.format("%1$d", number); 
     } 
    } 

    private static String[] numerals = { "zero", "one", "two", 
      "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
      "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", 
      "seventeen", "eighteen", "ninteen", "twenty", "thirty", "forty", 
      "fifty", "sixty", "seventy", "eighty", "ninety", "hundred" }; 

    private static long[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
      13, 14, 15, 16, 17, 18, 19, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; 

    private static ArrayList<String> list = new ArrayList<String>(
      Arrays.asList(numerals)); 

    public static long parseNumerals(String text) throws Exception { 
     long value = 0; 
     String[] words = text.replaceAll(" and ", " ").split("\\s"); 
     for (String word : words) { 
      if (!list.contains(word)) { 
       throw new Exception("Unknown token : " + word); 
      } 

      long subval = getValueOf(word); 
      if (subval == 100) { 
       if (value == 0) 
        value = 100; 
       else 
        value *= 100; 
      } else 
       value += subval; 
     } 

     return value; 
    } 

    private static long getValueOf(String word) { 
     return values[list.indexOf(word)]; 
    } 

    private static String[] words = { "trillion", "billion", "million", "thousand" }; 
    private static long[] digits = { 1000000000000L, 1000000000L, 1000000L, 1000L }; 

    public static long parse(String text) throws Exception { 
     text = text.toLowerCase().replaceAll("[\\-,]", " ").replaceAll(" and "," "); 
     long totalValue = 0; 
     boolean processed = false; 
     for (int n = 0; n < words.length; n++) { 
      int index = text.indexOf(words[n]); 
      if (index >= 0) { 
       String text1 = text.substring(0, index).trim(); 
       String text2 = text.substring(index + words[n].length()).trim(); 

       if (text1.equals("")) 
        text1 = "one"; 

       if (text2.equals("")) 
        text2 = "zero"; 

       totalValue = parseNumerals(text1) * digits[n] + parse(text2); 
       processed = true; 
       break; 
      } 
     } 

     if (processed) 
      return totalValue; 
     else 
      return parseNumerals(text); 
    } 


    public static void main(String[] args) throws Exception { 
     Scanner in = new Scanner(System.in); 
     System.out.print("Number in words : "); 
     String numberWordsText = in.nextLine(); 
     System.out.println("Value : " + 
       ConvertWordToNumber.WithSeparator(
       ConvertWordToNumber.parse(numberWordsText))); 
    } 
} 

独自のSolrフィルタを作成するために使用できます。ここ
はそれについてまともな記事です:

http://robotlibrarian.billdueber.com/building-a-solr-text-filter-for-normalizing-data/

に行うの際にSolrのコミュニティに貢献してください。 あなた自身のwikiページを書くことができます。

開始するには、この1つだけに同様のリンクをたどる:
http://wiki.apache.org/solr/SolrWordToNumberConverter

+1

ありがとう!私はいつかこれについて作業します。現時点では、一致のための低いしきい値でファジー検索を動作させることで問題を解決しました。私がこのようなフィルターを作ったら、私は間違いなくそれを戻します。 – Spoom

関連する問題