Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for analyzers and multifields #4574

Merged
merged 1 commit into from
Jun 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ https://github.com/elastic/beats/compare/v6.0.0-alpha2...master[Check the HEAD d
*Affecting all Beats*

- New cli subcommands interface. {pull}4420[4420]
- Allow source path matching in `add_docker_metadata` processor {pull}4495[4495]
- Allow source path matching in `add_docker_metadata` processor. {pull}4495[4495]
- Add support for analyzers and multifields in fields.yml. {pull}4574[4574]

*Filebeat*

Expand Down
72 changes: 47 additions & 25 deletions libbeat/template/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ var (
)

type Field struct {
Name string `config:"name"`
Type string `config:"type"`
Description string `config:"description"`
Format string `config:"format"`
ScalingFactor int `config:"scaling_factor"`
Fields Fields `config:"fields"`
ObjectType string `config:"object_type"`
Enabled *bool `config:"enabled"`
Name string `config:"name"`
Type string `config:"type"`
Description string `config:"description"`
Format string `config:"format"`
ScalingFactor int `config:"scaling_factor"`
Fields Fields `config:"fields"`
MultiFields Fields `config:"multi_fields"`
ObjectType string `config:"object_type"`
Enabled *bool `config:"enabled"`
Analyzer string `config:"analyzer"`
SearchAnalyzer string `config:"search_analyzer"`
Norms bool `config:"norms"`

path string
esVersion Version
Expand Down Expand Up @@ -94,20 +98,37 @@ func (f *Field) keyword() common.MapStr {
}

func (f *Field) text() common.MapStr {
property := f.getDefaultProperties()
properties := f.getDefaultProperties()

property["type"] = "text"
properties["type"] = "text"

if f.esVersion.IsMajor(2) {
property["type"] = "string"
property["index"] = "analyzed"
property["norms"] = common.MapStr{
"enabled": false,
properties["type"] = "string"
properties["index"] = "analyzed"
if !f.Norms {
properties["norms"] = common.MapStr{
"enabled": false,
}
}
} else {
property["norms"] = false
if !f.Norms {
properties["norms"] = false
}
}
return property

if f.Analyzer != "" {
properties["analyzer"] = f.Analyzer
}

if f.SearchAnalyzer != "" {
properties["search_analyzer"] = f.SearchAnalyzer
}

if len(f.MultiFields) > 0 {
properties["fields"] = f.MultiFields.process("", f.esVersion)
}

return properties
}

func (f *Field) array() common.MapStr {
Expand Down Expand Up @@ -152,6 +173,16 @@ func (f *Field) addDynamicTemplate(properties common.MapStr, matchType string) {
dynamicTemplates = append(dynamicTemplates, template)
}

func (f *Field) getDefaultProperties() common.MapStr {
// Currently no defaults exist
property := common.MapStr{}
if f.Enabled != nil {
property["enabled"] = *f.Enabled
}

return property
}

// Recursively generates the correct key based on the dots
// The mapping requires "properties" between each layer. This is added here.
func generateKey(key string) string {
Expand All @@ -161,12 +192,3 @@ func generateKey(key string) string {
}
return key
}

func (f *Field) getDefaultProperties() common.MapStr {
// Currently no defaults exist
property := common.MapStr{}
if f.Enabled != nil {
property["enabled"] = *f.Enabled
}
return property
}
67 changes: 67 additions & 0 deletions libbeat/template/field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,73 @@ func TestField(t *testing.T) {
"enabled": false,
},
},
{
field: Field{Type: "text", Analyzer: "autocomplete"},
method: func(f Field) common.MapStr { return f.text() },
output: common.MapStr{
"type": "text",
"analyzer": "autocomplete",
"norms": false,
},
},
{
field: Field{Type: "text", Analyzer: "autocomplete", Norms: true},
method: func(f Field) common.MapStr { return f.text() },
output: common.MapStr{
"type": "text",
"analyzer": "autocomplete",
},
},
{
field: Field{Type: "text", SearchAnalyzer: "standard", Norms: true},
method: func(f Field) common.MapStr { return f.text() },
output: common.MapStr{
"type": "text",
"search_analyzer": "standard",
},
},
{
field: Field{Type: "text", Analyzer: "autocomplete", SearchAnalyzer: "standard", Norms: true},
method: func(f Field) common.MapStr { return f.text() },
output: common.MapStr{
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard",
},
},
{
field: Field{Type: "text", MultiFields: Fields{Field{Name: "raw", Type: "keyword"}}, Norms: true},
method: func(f Field) common.MapStr { return f.text() },
output: common.MapStr{
"type": "text",
"fields": common.MapStr{
"raw": common.MapStr{
"type": "keyword",
"ignore_above": 1024,
},
},
},
},
{
field: Field{Type: "text", MultiFields: Fields{
Field{Name: "raw", Type: "keyword"},
Field{Name: "indexed", Type: "text"},
}, Norms: true},
method: func(f Field) common.MapStr { return f.text() },
output: common.MapStr{
"type": "text",
"fields": common.MapStr{
"raw": common.MapStr{
"type": "keyword",
"ignore_above": 1024,
},
"indexed": common.MapStr{
"type": "text",
"norms": false,
},
},
},
},
}

for _, test := range tests {
Expand Down