Categorygithub.com/varfrog/opensearchutil
modulepackage
0.17.0
Repository: https://github.com/varfrog/opensearchutil.git
Documentation: pkg.go.dev

# README

OpenSearchUtil

Utilities for working with OpenSearch.

  • IndexGenerator: given an object, makes an OpenSearch index template,
  • MappingPropertiesBuilder and generation of index mappings: given an object, makes an OpenSearch index mapping,
  • Field types: go types for struct fields that:
    • when the struct is marshalled into JSON, the fields get marshalled into valid OpenSearch types,
    • when generating an index mapping JSON, the fields get assigned the appropriate OpenSearch type and format.

IndexGenerator

package main

import (
  _ "embed"
  "fmt"
  "github.com/varfrog/opensearchutil"
  "os"
)

func main() {
  type location struct {
    FullAddress string
    Confirmed   bool
  }
  type person struct {
    Name           string
    Aliases        []string
    Email          string `opensearch:"type:keyword"`
    DOB            opensearchutil.TimeBasicDateTimeNoMillis
    Age            uint8
    AccountBalance float64
    IsDead         bool
    HomeLoc        location
    WorkLoc        *location
    SocialSecurity *string `opensearch:"index_prefixes:min_chars=3;max_chars=5"`
  }

  builder := opensearchutil.NewMappingPropertiesBuilder()
  jsonGenerator := opensearchutil.NewIndexGenerator()

  mappingProperties, err := builder.BuildMappingProperties(person{})
  if err != nil {
    fmt.Printf("BuildMappingProperties: %v", err)
    os.Exit(1)
  }

  indexJson, err := jsonGenerator.GenerateIndexJson(
    mappingProperties, &opensearchutil.IndexSettings{
      NumberOfShards: opensearchutil.MakePtr(uint16(1)),
    },
    opensearchutil.WithStrictMapping(true))
  if err != nil {
    fmt.Printf("GenerateIndexJson: %v", err)
    os.Exit(1)
  }
  fmt.Printf("%s\n", string(indexJson))
}

Output:

{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "account_balance": {
        "type": "float"
      },
      "age": {
        "type": "integer"
      },
      "aliases": {
        "type": "text"
      },
      "dob": {
        "format": "basic_date_time_no_millis",
        "type": "date"
      },
      "email": {
        "type": "keyword"
      },
      "home_loc": {
        "properties": {
          "confirmed": {
            "type": "boolean"
          },
          "full_address": {
            "type": "text"
          }
        }
      },
      "is_dead": {
        "type": "boolean"
      },
      "name": {
        "type": "text"
      },
      "social_security": {
        "index_prefixes": {
          "max_chars": "5",
          "min_chars": "3"
        },
        "type": "text"
      },
      "work_loc": {
        "properties": {
          "confirmed": {
            "type": "boolean"
          },
          "full_address": {
            "type": "text"
          }
        }
      }
    }
  },
  "settings": {
    "number_of_shards": 1
  }
}

The resulting JSON contents is then used in a request to the Create index API request. Also specify "settings" and "aliases" that suit your needs.

MappingPropertiesBuilder

MappingPropertiesBuilder takes in an object and generates an index mapping for it.

package main

import (
  "fmt"
  "github.com/varfrog/opensearchutil"
  "os"
)

func main() {
  type address struct {
    streetName string
  }

  type person struct {
    Name      string
    Email     string `opensearch:"type:keyword"`
    Addresses []address
  }

  mappingPropertiesBuilder := opensearchutil.NewMappingPropertiesBuilder()
  generator := opensearchutil.NewIndexGenerator()

  mappingProperties, err := mappingPropertiesBuilder.BuildMappingProperties(person{})
  if err != nil {
    fmt.Printf("BuildMappingProperties: %v", err)
    os.Exit(1)
  }

  indexJson, err := generator.GenerateMappingsJson(mappingProperties)
  if err != nil {
    fmt.Printf("GenerateMappingsJson: %v", err)
    os.Exit(1)
  }
  fmt.Printf("%s\n", string(indexJson))
}

Output:

{
  "properties": {
    "addresses": {
      "properties": {
        "street_name": {
          "type": "text"
        }
      }
    },
    "email": {
      "type": "keyword"
    },
    "name": {
      "type": "text"
    }
  }
}

Field Types

package main

import (
	"encoding/json"
	"fmt"
	"github.com/varfrog/opensearchutil"
	"os"
	"time"
)

func main() {
	type dates struct {
		DateA opensearchutil.TimeBasicDate             `json:"date_a"`
		DateB opensearchutil.TimeBasicDateTimeNoMillis `json:"date_b"`
		DateC opensearchutil.TimeBasicDateTime         `json:"date_c"`
	}

	t := time.Now()
	d := dates{
		DateA: opensearchutil.TimeBasicDate(t),
		DateB: opensearchutil.TimeBasicDateTimeNoMillis(t),
		DateC: opensearchutil.TimeBasicDateTime(t),
	}

	// When generating an index mapping JSON, the fields get assigned the approprate OpenSearch type and format
	//
	mappingProperties, err := opensearchutil.NewMappingPropertiesBuilder().BuildMappingProperties(d)
	if err != nil {
		fmt.Printf("BuildMappingProperties: %v", err)
		os.Exit(1)
	}
	jsonBytes, err := opensearchutil.NewIndexGenerator().GenerateIndexJson(mappingProperties, nil)
	if err != nil {
		fmt.Printf("GenerateIndexJson: %v", err)
		os.Exit(1)
	}
	fmt.Printf("Mapping JSON:\n%s\n", string(jsonBytes))

	// When marshalling into JSON, the fields marshall into the approprate formats:
	//
	jsonBytes, err = json.MarshalIndent(&d, "", "  ")
	if err != nil {
		fmt.Printf("json.MarshalIndent: %v", err)
		os.Exit(1)
	}
	fmt.Printf("\nDocument body:\n%s\n", string(jsonBytes))
}

Output:

Mapping JSON:
{
   "mappings": {
      "properties": {
         "date_a": {
            "format": "basic_date",
            "type": "date"
         },
         "date_b": {
            "format": "basic_date_time_no_millis",
            "type": "date"
         },
         "date_c": {
            "format": "basic_date_time",
            "type": "date"
         }
      }
   }
}

Document body:
{
  "date_a": "20230223",
  "date_b": "20230223T224633+02:00",
  "date_c": "20230223T224633.808+02:00"
}

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
OmitUnsupportedTypes makes the builder not complain about types it cannot support.
goland:noinspection GoUnusedExportedFunction.
goland:noinspection GoUnusedExportedFunction.
No description provided by the author
WithStrictMapping adds "dynamic: "strict" to "mappings".

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

No description provided by the author

# Structs

No description provided by the author
IndexSettings allows to specify settings of an index, at its creation.
No description provided by the author
MappingProperty corresponds to mappings.properties of a mapping JSON.
No description provided by the author
No description provided by the author

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
OpenSearchDateType tells MappingPropertiesBuilder that a type is a "date" OpenSearch type.

# Type aliases

No description provided by the author
No description provided by the author
No description provided by the author