Skip to content

Instantly share code, notes, and snippets.

@popsUlfr
Last active March 30, 2020 17:21
Show Gist options
  • Save popsUlfr/d9233df57643e567f219d3d469e1002f to your computer and use it in GitHub Desktop.
Save popsUlfr/d9233df57643e567f219d3d469e1002f to your computer and use it in GitHub Desktop.
github.com/blevesearch/bleve v0.8.2 mapping problem with french text
package main
import (
"fmt"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/analysis/lang/fr"
)
type WebResource struct {
TextContent string `json:"text_content"`
}
func (WebResource) Type() string {
return "webresource"
}
var exampleWR = WebResource{
TextContent: `_Comment aider les personnes très éloignées de l’emploi à développer des activités utiles au plus grand nombre tous ?_
## [](#le-contexte) Le contexte
“TZCLD: Territoire zéro chômeur de longue durée” est une expérimentation sur territoire français menée afin de trouver une nouvelle manière de prendre en charge les personnes très éloignées de l’emploi.
## [](#la-problématique) La problématique
Nous avons décidé de nous immiscer dans le dispositif TZCLD afin d’aider à la prise en charge et à la reconversion professionnelle de personnes très éloignées de l’emploi sur le territoire lillois.`,
}
func main() {
wrmap := bleve.NewDocumentStaticMapping()
txtmap := bleve.NewTextFieldMapping()
txtmap.Analyzer = fr.AnalyzerName // commenting this line makes it work ?
wrmap.AddFieldMappingsAt("text_content", txtmap)
im := bleve.NewIndexMapping()
im.AddDocumentMapping(WebResource{}.Type(), wrmap)
index, _ := bleve.NewMemOnly(im)
index.Index("1", exampleWR)
//q := bleve.NewMatchAllQuery() // to see all the contents of the index
q := bleve.NewQueryStringQuery("chômeur")
sreq := bleve.NewSearchRequest(q)
sreq.Highlight = bleve.NewHighlightWithStyle("html")
sreq.Fields = []string{"*"}
sres, _ := index.Search(sreq)
fmt.Println(sres.String())
}
package main
import (
"fmt"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/analysis"
"github.com/blevesearch/bleve/analysis/char/asciifolding"
"github.com/blevesearch/bleve/analysis/lang/fr"
"github.com/blevesearch/bleve/registry"
)
type WebResource struct {
TextContent string `json:"text_content"`
}
func (WebResource) Type() string {
return "webresource"
}
var exampleWR = WebResource{
TextContent: `_Comment aider les personnes très éloignées de l’emploi à développer des activités utiles au plus grand nombre tous ?_
## [](#le-contexte) Le contexte
“TZCLD: Territoire zéro chômeur de longue durée” est une expérimentation sur territoire français menée afin de trouver une nouvelle manière de prendre en charge les personnes très éloignées de l’emploi.
## [](#la-problématique) La problématique
Nous avons décidé de nous immiscer dans le dispositif TZCLD afin d’aider à la prise en charge et à la reconversion professionnelle de personnes très éloignées de l’emploi sur le territoire lillois.`,
}
func main() {
registry.RegisterAnalyzer("frplus", func(config map[string]interface{}, cache *registry.Cache) (*analysis.Analyzer, error) {
asciiFoldingCharFilter, err := cache.CharFilterNamed(asciifolding.Name)
if err != nil {
return nil, err
}
frAnalyzer, err := cache.AnalyzerNamed(fr.AnalyzerName)
if err != nil {
return nil, err
}
frAnalyzer.CharFilters = append(frAnalyzer.CharFilters, asciiFoldingCharFilter)
return frAnalyzer, nil
})
wrmap := bleve.NewDocumentStaticMapping()
txtmap := bleve.NewTextFieldMapping()
txtmap.Analyzer = "frplus"
wrmap.AddFieldMappingsAt("text_content", txtmap)
im := bleve.NewIndexMapping()
im.AddDocumentMapping(WebResource{}.Type(), wrmap)
index, _ := bleve.NewMemOnly(im)
index.Index("1", exampleWR)
//q := bleve.NewMatchAllQuery() // to see all the contents of the index
q := bleve.NewQueryStringQuery("chomeur")
sreq := bleve.NewSearchRequest(q)
sreq.Highlight = bleve.NewHighlightWithStyle("html")
sreq.Fields = []string{"*"}
sres, _ := index.Search(sreq)
fmt.Println(sres.String())
}
package main
import (
"fmt"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/analysis"
"github.com/blevesearch/bleve/analysis/char/asciifolding"
"github.com/blevesearch/bleve/analysis/lang/fr"
"github.com/blevesearch/bleve/registry"
)
type WebResource struct {
TextContent string `json:"text_content"`
}
func (WebResource) Type() string {
return "webresource"
}
var exampleWR = WebResource{
TextContent: `_Comment aider les personnes très éloignées de l’emploi à développer des activités utiles au plus grand nombre tous ?_
## [](#le-contexte) Le contexte
“TZCLD: Territoire zéro chômeur de longue durée” est une expérimentation sur territoire français menée afin de trouver une nouvelle manière de prendre en charge les personnes très éloignées de l’emploi.
## [](#la-problématique) La problématique
Nous avons décidé de nous immiscer dans le dispositif TZCLD afin d’aider à la prise en charge et à la reconversion professionnelle de personnes très éloignées de l’emploi sur le territoire lillois.`,
}
type AsciiFoldingTokenFilter struct {
asciifoldingCharFilter analysis.CharFilter
}
func (tf *AsciiFoldingTokenFilter) Filter(ts analysis.TokenStream) analysis.TokenStream {
for _, t := range ts {
t.Term = tf.asciifoldingCharFilter.Filter(t.Term)
}
return ts
}
func main() {
registry.RegisterTokenFilter("asciifoldingtokenfilter", func(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) {
asciifoldingCharFilter, err := cache.CharFilterNamed(asciifolding.Name)
if err != nil {
return nil, err
}
return &AsciiFoldingTokenFilter{asciifoldingCharFilter: asciifoldingCharFilter}, nil
})
registry.RegisterAnalyzer("frplus", func(config map[string]interface{}, cache *registry.Cache) (*analysis.Analyzer, error) {
frAnalyzer, err := cache.AnalyzerNamed(fr.AnalyzerName)
if err != nil {
return nil, err
}
asciiFoldingTokenFilter, err := cache.TokenFilterNamed("asciifoldingtokenfilter")
if err != nil {
return nil, err
}
frAnalyzer.TokenFilters = append(frAnalyzer.TokenFilters, asciiFoldingTokenFilter)
return frAnalyzer, nil
})
im := bleve.NewIndexMapping()
im.DefaultAnalyzer = "frplus"
index, _ := bleve.NewMemOnly(im)
index.Index("1", exampleWR)
//q := bleve.NewMatchAllQuery() // to see all the contents of the index
q := bleve.NewQueryStringQuery("chomeur")
sreq := bleve.NewSearchRequest(q)
sreq.Highlight = bleve.NewHighlightWithStyle("html")
sreq.Fields = []string{"*"}
sres, _ := index.Search(sreq)
fmt.Println(sres.String())
}
package main
import (
"bytes"
"fmt"
"strings"
"github.com/abadojack/whatlanggo"
"github.com/blevesearch/bleve"
"github.com/blevesearch/bleve/analysis"
"github.com/blevesearch/bleve/analysis/char/asciifolding"
"github.com/blevesearch/bleve/analysis/lang/en"
"github.com/blevesearch/bleve/registry"
_ "github.com/blevesearch/bleve/analysis/lang/ar"
_ "github.com/blevesearch/bleve/analysis/lang/bg"
_ "github.com/blevesearch/bleve/analysis/lang/ca"
_ "github.com/blevesearch/bleve/analysis/lang/cjk"
_ "github.com/blevesearch/bleve/analysis/lang/ckb"
_ "github.com/blevesearch/bleve/analysis/lang/cs"
_ "github.com/blevesearch/bleve/analysis/lang/da"
_ "github.com/blevesearch/bleve/analysis/lang/de"
_ "github.com/blevesearch/bleve/analysis/lang/el"
_ "github.com/blevesearch/bleve/analysis/lang/en"
_ "github.com/blevesearch/bleve/analysis/lang/es"
_ "github.com/blevesearch/bleve/analysis/lang/eu"
_ "github.com/blevesearch/bleve/analysis/lang/fa"
_ "github.com/blevesearch/bleve/analysis/lang/fi"
_ "github.com/blevesearch/bleve/analysis/lang/fr"
_ "github.com/blevesearch/bleve/analysis/lang/ga"
_ "github.com/blevesearch/bleve/analysis/lang/gl"
_ "github.com/blevesearch/bleve/analysis/lang/hi"
_ "github.com/blevesearch/bleve/analysis/lang/hu"
_ "github.com/blevesearch/bleve/analysis/lang/hy"
_ "github.com/blevesearch/bleve/analysis/lang/id"
_ "github.com/blevesearch/bleve/analysis/lang/in"
_ "github.com/blevesearch/bleve/analysis/lang/it"
_ "github.com/blevesearch/bleve/analysis/lang/nl"
_ "github.com/blevesearch/bleve/analysis/lang/no"
_ "github.com/blevesearch/bleve/analysis/lang/pt"
_ "github.com/blevesearch/bleve/analysis/lang/ro"
_ "github.com/blevesearch/bleve/analysis/lang/ru"
_ "github.com/blevesearch/bleve/analysis/lang/sv"
_ "github.com/blevesearch/bleve/analysis/lang/tr"
_ "github.com/blevesearch/blevex/lang/ja"
_ "github.com/blevesearch/blevex/lang/th"
)
type WebResource struct {
TextContent string `json:"text_content"`
}
func (WebResource) Type() string {
return "webresource"
}
var exampleWR = WebResource{
TextContent: `_Comment aider les personnes très éloignées de l’emploi à développer des activités utiles au plus grand nombre tous ?_
## [](#le-contexte) Le contexte
“TZCLD: Territoire zéro chômeur de longue durée” est une expérimentation sur territoire français menée afin de trouver une nouvelle manière de prendre en charge les personnes très éloignées de l’emploi.
## [](#la-problématique) La problématique
Nous avons décidé de nous immiscer dans le dispositif TZCLD afin d’aider à la prise en charge et à la reconversion professionnelle de personnes très éloignées de l’emploi sur le territoire lillois.`,
}
type DetectLangAppendCharFilter struct {
defaultLang string
}
func (c *DetectLangAppendCharFilter) Filter(input []byte) []byte {
var langs []string
hasDefLang := false
if len(input) > 0 {
sInput := string(input)
options := whatlanggo.Options{
Blacklist: map[whatlanggo.Lang]bool{},
}
for i := 0; i < 8; i++ {
info := whatlanggo.DetectWithOptions(sInput, options)
options.Blacklist[info.Lang] = true
lang := info.Lang.Iso6391()
langs = append(langs, lang)
if !hasDefLang && lang == c.defaultLang {
hasDefLang = true
}
if !info.IsReliable() {
if !hasDefLang {
langs = append(langs, c.defaultLang)
hasDefLang = true
}
break
}
}
}
if !hasDefLang {
langs = append(langs, c.defaultLang)
}
input = append(input, []byte(";"+strings.Join(langs, ","))...)
return input
}
var germanSpecialReplacer = strings.NewReplacer(
"ä", "ae",
"Ä", "AE",
"ö", "oe",
"Ö", "OE",
"ü", "ue",
"Ü", "UE",
"ß", "ss",
"ẞ", "SS",
)
type GermanSpecialTokenFilter struct {
}
func (c *GermanSpecialTokenFilter) Filter(ts analysis.TokenStream) analysis.TokenStream {
var output bytes.Buffer
for _, t := range ts {
germanSpecialReplacer.WriteString(&output, string(t.Term))
newTerm := output.Bytes()
t.Term = make([]byte, len(newTerm))
copy(t.Term, newTerm)
output.Reset()
}
return ts
}
type DynamicLangTokenizer struct {
cache *registry.Cache
defaultAnalyzer *analysis.Analyzer
}
func (d *DynamicLangTokenizer) Tokenize(input []byte) analysis.TokenStream {
beg := bytes.LastIndexByte(input, ';')
if beg >= 0 {
langPart := input[beg+1:]
input = input[:beg]
langs := bytes.Split(langPart, []byte{','})
var ts analysis.TokenStream
for _, lang := range langs {
sLang := string(lang)
analyzer, err := d.cache.AnalyzerNamed(sLang)
if err != nil {
continue
}
ts = append(ts, analyzer.Analyze(input)...)
}
return ts
}
return d.defaultAnalyzer.Analyze(input)
}
type AsciiFoldingTokenFilter struct {
asciifoldingCharFilter analysis.CharFilter
}
func (tf *AsciiFoldingTokenFilter) Filter(ts analysis.TokenStream) analysis.TokenStream {
for _, t := range ts {
t.Term = tf.asciifoldingCharFilter.Filter(t.Term)
}
return ts
}
func main() {
registry.RegisterCharFilter("detectlangappend", func(config map[string]interface{}, cache *registry.Cache) (analysis.CharFilter, error) {
if dLang, ok := config["default_lang"].(string); ok {
return &DetectLangAppendCharFilter{defaultLang: dLang}, nil
}
return &DetectLangAppendCharFilter{defaultLang: en.AnalyzerName}, nil
})
registry.RegisterTokenFilter("germanspecialtokenfilter", func(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) {
return &GermanSpecialTokenFilter{}, nil
})
registry.RegisterTokenFilter("asciifoldingtokenfilter", func(config map[string]interface{}, cache *registry.Cache) (analysis.TokenFilter, error) {
asciifoldingCharFilter, err := cache.CharFilterNamed(asciifolding.Name)
if err != nil {
return nil, err
}
return &AsciiFoldingTokenFilter{asciifoldingCharFilter: asciifoldingCharFilter}, nil
})
registry.RegisterTokenizer("dynamiclangtokenizer", func(config map[string]interface{}, cache *registry.Cache) (analysis.Tokenizer, error) {
var defaultAnalyzer *analysis.Analyzer
if dLang, ok := config["default_lang"].(string); ok {
var err error
defaultAnalyzer, err = cache.AnalyzerNamed(dLang)
if err != nil {
defaultAnalyzer, _ = cache.AnalyzerNamed(en.AnalyzerName)
}
} else {
defaultAnalyzer, _ = cache.AnalyzerNamed(en.AnalyzerName)
}
return &DynamicLangTokenizer{
cache: cache,
defaultAnalyzer: defaultAnalyzer,
}, nil
})
registry.RegisterAnalyzer("dynamiclang", func(config map[string]interface{}, cache *registry.Cache) (*analysis.Analyzer, error) {
detectLangAppendCharFilter, err := cache.CharFilterNamed("detectlangappend")
if err != nil {
return nil, err
}
dynamicLangTokenizer, err := cache.TokenizerNamed("dynamiclangtokenizer")
if err != nil {
return nil, err
}
germanSpecialTokenFilter, err := cache.TokenFilterNamed("germanspecialtokenfilter")
if err != nil {
return nil, err
}
asciiFoldingTokenFilter, err := cache.TokenFilterNamed("asciifoldingtokenfilter")
if err != nil {
return nil, err
}
rv := analysis.Analyzer{
CharFilters: []analysis.CharFilter{
detectLangAppendCharFilter,
},
Tokenizer: dynamicLangTokenizer,
TokenFilters: []analysis.TokenFilter{
germanSpecialTokenFilter,
asciiFoldingTokenFilter,
},
}
return &rv, nil
})
im := bleve.NewIndexMapping()
im.DefaultAnalyzer = "dynamiclang"
index, _ := bleve.NewMemOnly(im)
index.Index("1", exampleWR)
//q := bleve.NewMatchAllQuery() // to see all the contents of the index
q := bleve.NewQueryStringQuery("chomeur")
sreq := bleve.NewSearchRequest(q)
sreq.Highlight = bleve.NewHighlightWithStyle("html")
sreq.Fields = []string{"*"}
sres, _ := index.Search(sreq)
fmt.Println(sres.String())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment