▶ gradle -v
------------------------------------------------------------
Gradle 7.1
------------------------------------------------------------
Build time: 2021-06-14 14:47:26 UTC
Revision: 989ccc9952b140ee6ab88870e8a12f1b2998369e
Kotlin: 1.4.31
Groovy: 3.0.7
Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM: 11.0.3 (Amazon.com Inc. 11.0.3+7-LTS)
OS: Mac OS X 10.15.6 x86_64
func main() {
// DBと接続
config := stalefish.NewDBConfig("root", "password", "127.0.0.1", "3306", "stalefish")
db, _ := stalefish.NewDBClient(config) // エラーハンドリングは省略
storage := stalefish.NewStorageRdbImpl(db) // 永続化を責務にするストレージ
analyzer := stalefish.NewAnalyzer([]stalefish.CharFilter{}, stalefish.StandardTokenizer{}, []stalefish.TokenFilter{stalefish.StemmerFilter{}, stalefish.LowercaseFilter{}, stalefish.StopWordFilter{}}) // 文書を単語に分割するアナライザ
indexer := stalefish.NewIndexer(storage, analyzer, make(stalefish.InvertedIndexMap)) // 転置インデックスを作成するインデクサ(アナライザーとストレージを注入する)// ドキュメントを追加
indexer.AddDocument(stalefish.NewDocument("You can watch lots of interesting dramas on Amazon Prime."))
indexer.AddDocument(stalefish.NewDocument("Forest phenomena in the Amazon are a prime concern."))
indexer.AddDocument(stalefish.NewDocument("I watched amazon prime until late at night yesterday."))
indexer.AddDocument(stalefish.NewDocument("Breaking Bad is a very jarring drama."))
// フレーズ検索を行う
q := stalefish.NewPhraseQuery("amAzon PRime", analyzer)
seacher := q.Searcher(storage)
result, _ := seacher.Search() // エラーハンドリングは省略
fmt.Println(result)
// result: [{1 You can watch lots of interesting dramas on Amazon Prime.} {3 I watched amazon prime until late at night yesterday.}]
}
analyzer := stalefish.Analyzer{
[]stalefish.CharFilter{stalefish.MappingCharFilter{map[string]string{":)": "_happy_", ":(": "_sad_"}}},
stalefish.StandardTokenizer{},
[]stalefish.TokenFilter{stalefish.LowercaseFilter{}, stalefish.StopWordFilter{}, stalefish.StemmerFilter{}},
}
fmt.Println(analyzer.Analyze("I have a lot of TASKs. I am very sad :("))
// output: ["lot", "task", "am", "very", "sad", "sad"]
アドベントカレンダーに12月11日に記事投稿するとなり、その日までにできたところを記事にしようと考えていましたが、ドキュメントをインデキシングしてフレーズ検索をして結果を返すというキリが良いところまで実装できて良かったです。
Done is better than perfectの精神で実装しており、まだおもちゃでバグだらけ残念な実装になっている部分も多いですが誰かの役に立てば嬉しいです。
type IntSet struct {
words []uint64
}
func (s *IntSet) Has(x int) bool {
word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0
}
func (s *IntSet) Add(x int) {
word, bit := x/64, uint(x%64)
for word >= len(s.words) {
s.words = append(s.words, 0)
}
s.words[word] |= 1 << bit
}
func (s *IntSet) Remove(x int) {
word, bit := x/64, uint(x%64)
if word > len(s.words) {
return
}
s.words[word] &= ^(1 << bit)
}
func (s *IntSet) UnionWith(t *IntSet) {
for i, tword := range t.words {
if i < len(s.words) {
s.words[i] |= tword
} else {
s.words = append(s.words, tword)
}
}
}
func (s *IntSet) IntersectWith(t *IntSet) {
for i, sword := range s.words {
sword &= t.words[i]
}
s.words = s.words[:len(t.words)]
}