diff --git a/search/document_store.go b/search/document_store.go
index bd5e4e32606b2f835d222c4f0ca5f08a88ace940..bec67551c3ff54122193b621b13254bcae621d23 100644
--- a/search/document_store.go
+++ b/search/document_store.go
@@ -90,7 +90,7 @@ func (w *writer) DocumentStore(name string, tmpl interface{}) (DocumentStore, er
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to marshal index mappings")
 	}
-	logger.Debugf("%s Index Mappings: %s", structType, string(ds.jsonMappings))
+	logger.Infof("%s Index Mappings: %s", structType, string(ds.jsonMappings))
 
 	//define search response type
 	//similar to SearchResponseBody
diff --git a/search/document_store_test.go b/search/document_store_test.go
index 788d43af4788469828e1854b4e1e65f6e0b7b6bc..2c168d1e37f20c761709d9d74730083135308ef4 100644
--- a/search/document_store_test.go
+++ b/search/document_store_test.go
@@ -1,8 +1,11 @@
 package search_test
 
 import (
+	"fmt"
 	"math/rand"
+	"strings"
 	"testing"
+	"time"
 
 	"github.com/google/uuid"
 	"gitlab.com/uafrica/go-utils/logger"
@@ -32,7 +35,7 @@ func testDocuments(t *testing.T, c search.Config) {
 	}
 
 	indexName := "go-utils-search-docs-test"
-	ds, err := a.DocumentStore(indexName, testDocument{})
+	ds, err := a.DocumentStore(indexName, SearchOrder{})
 	if err != nil {
 		t.Fatalf("failed to create document store: %+v", err)
 	}
@@ -64,10 +67,32 @@ func testDocuments(t *testing.T, c search.Config) {
 	for i := 0; i < N; i++ {
 		//make a random document
 		id := uuid.New().String()
-		doc := testDocument{
-			Buyer:  buyers[rand.Intn(len(buyers))],
-			Seller: sellers[rand.Intn(len(sellers))],
-			Items:  []docItem{},
+		buyer := buyers[rand.Intn(len(buyers))]
+		seller := sellers[rand.Intn(len(sellers))]
+		doc := SearchOrder{
+			ID:                            int64(i + 1),
+			AccountID:                     int64(i + 2),
+			AccountOrderNumber:            int64(i * 2),
+			ChannelID:                     int64(i),
+			ChannelOrderNumber:            fmt.Sprintf("CHO-%d", i),
+			ChannelOrderReference:         fmt.Sprintf("REF-%05d", i),
+			CustomerName:                  buyer,
+			CustomerEmail:                 strings.ToLower(buyer + "@home.net"),
+			CustomerPhone:                 "123456789",
+			DeliveryAddress:               "My Street",
+			Currency:                      "ZAR",
+			Items:                         []SearchOrderItem{},
+			TotalPrice:                    0,
+			TotalWeightKg:                 0,
+			TotalQty:                      0,
+			TotalFulfilledQty:             0,
+			Status:                        OrderStatusNew,
+			PaymentStatus:                 OrderPaymentStatusUnpaid,
+			TimeCreated:                   time.Now(),
+			TimeModified:                  nil,
+			Tags:                          "1(blue),2(red)",
+			BuyerSelectedShippingCost:     1.23,
+			BuyerSelectedShippingProvider: seller,
 		}
 		for i := 0; i < rand.Intn(5)+1; i++ {
 			itemInfo := itemInfos[nextItem]
@@ -75,14 +100,15 @@ func testDocuments(t *testing.T, c search.Config) {
 			if nextItem >= len(itemInfos) {
 				nextItem = 0
 			}
-			item := docItem{
+			item := SearchOrderItem{
+				SKU:         fmt.Sprintf("SKU-%s-%03d", itemInfo.Name[:3], i),
 				Description: itemInfo.Name,
-				UnitCost:    itemInfo.Cost,
+				UnitPrice:   itemInfo.Cost,
 				Qty:         rand.Intn(3) + 1,
 			}
 			doc.Items = append(doc.Items, item)
-			doc.TotalCost += item.UnitCost * float64(item.Qty)
-			doc.TotalItems += item.Qty
+			doc.TotalPrice += item.UnitPrice * float64(item.Qty)
+			doc.TotalQty += item.Qty
 		}
 
 		//add to the search
@@ -117,22 +143,81 @@ func testDocuments(t *testing.T, c search.Config) {
 	t.Logf("Done")
 }
 
-type testDocument struct {
-	//UUID       string    `json:"uuid"`
-	Buyer      string    `json:"buyer" search:"keyword"`
-	Seller     string    `json:"seller" search:"keyword"`
-	Items      []docItem `json:"items"`
-	TotalCost  float64   `json:"total_cost"`
-	TotalItems int       `json:"total_items"`
-}
+// type testDocument struct {
+// 	//UUID       string    `json:"uuid"`
+// 	Buyer      string    `json:"buyer" search:"keyword"`
+// 	Seller     string    `json:"seller" search:"keyword"`
+// 	Items      []docItem `json:"items"`
+// 	TotalCost  float64   `json:"total_cost"`
+// 	TotalItems int       `json:"total_items"`
+// }
 
-type docItem struct {
-	Description string  `json:"description" search:"keyword"`
-	UnitCost    float64 `json:"unit_cost"`
-	Qty         int     `json:"qty"`
-}
+// type docItem struct {
+// 	Description string  `json:"description" search:"keyword"`
+// 	UnitCost    float64 `json:"unit_cost"`
+// 	Qty         int     `json:"qty"`
+// }
 
 type testItemInfo struct {
 	Name string
 	Cost float64
 }
+
+type SearchOrder struct {
+	ID                            int64              `json:"id"`
+	AccountID                     int64              `json:"account_id"                search:"keyword"`
+	AccountOrderNumber            int64              `json:"account_order_number"`
+	ChannelID                     int64              `json:"channel,omitempty"         search:"keyword"`
+	ChannelOrderNumber            string             `json:"channel_order_number,omitempty"`
+	ChannelOrderReference         string             `json:"channel_order_reference,omitempty"`
+	CustomerName                  string             `json:"customer_name,omitempty"`
+	CustomerEmail                 string             `json:"customer_email,omitempty"`
+	CustomerPhone                 string             `json:"customer_phone,omitempty"`
+	DeliveryAddress               string             `json:"delivery_address,omitempty"`
+	Currency                      string             `json:"currency"                  search:"keyword"`
+	Items                         []SearchOrderItem  `json:"items,omitempty"`
+	TotalPrice                    float64            `json:"total_price"`
+	TotalWeightKg                 float64            `json:"total_weight_kg"`
+	TotalQty                      int                `json:"total_qty"`
+	TotalFulfilledQty             int                `json:"total_fulfilled_qty"`
+	Status                        OrderStatus        `json:"status"                    search:"keyword"`
+	PaymentStatus                 OrderPaymentStatus `json:"payment_status"            search:"keyword"`
+	TimeCreated                   time.Time          `json:"time_created"`
+	TimeModified                  *time.Time         `json:"time_modified,omitempty"`
+	Tags                          string             `json:"tags"                      search:"keyword"` //CSV or tags sorted, so [A,B] and [B,A] both -> "A,B" keyword
+	BuyerSelectedShippingCost     float64            `json:"buyer_selected_shipping_cost,omitempty"`
+	BuyerSelectedShippingProvider string             `json:"buyer_selected_shipping_provider,omitempty"`
+}
+
+type SearchOrderItem struct {
+	SKU           string  `json:"sku"                          search:"keyword"`
+	Description   string  `json:"description"                  search:"keyword"`
+	Vendor        string  `json:"vendor"                       search:"keyword"`
+	UnitPrice     float64 `json:"unit_price"`
+	UnitWeightKg  float64 `json:"unit_weight_kg"`
+	Qty           int     `json:"qty"`
+	FulfilledQty  int     `json:"fulfilled_qty"`
+	TotalPrice    float64 `json:"total_price"`
+	TotalWeightKg float64 `json:"total_weight_kg"`
+}
+
+type OrderStatus string
+
+const (
+	OrderStatusNew       OrderStatus = "new"
+	OrderStatusCompleted OrderStatus = "completed"
+	OrderStatusCancelled OrderStatus = "cancelled"
+)
+
+type OrderPaymentStatus string
+
+const (
+	OrderPaymentStatusUnpaid            OrderPaymentStatus = "unpaid"
+	OrderPaymentStatusPending           OrderPaymentStatus = "pending"
+	OrderPaymentStatusPartiallyPaid     OrderPaymentStatus = "partially-paid"
+	OrderPaymentStatusPaid              OrderPaymentStatus = "paid"
+	OrderPaymentStatusPartiallyRefunded OrderPaymentStatus = "partially-refunded"
+	OrderPaymentStatusRefunded          OrderPaymentStatus = "refunded"
+	OrderPaymentStatusVoided            OrderPaymentStatus = "voided"
+	OrderPaymentStatusAuthorised        OrderPaymentStatus = "authorised"
+)
diff --git a/search/time_series.go b/search/time_series.go
index 294dab773b3c658be5350d7f647da303c38385b8..4420e3f13fe04db4a2ad64f5a21b8d309d2c9aa2 100644
--- a/search/time_series.go
+++ b/search/time_series.go
@@ -152,10 +152,23 @@ func structMappingProperties(structType reflect.Type) (map[string]MappingPropert
 			fieldMapping = MappingProperty{Type: "long"}
 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 			fieldMapping = MappingProperty{Type: "long"}
+		case reflect.Float32, reflect.Float64:
+			fieldMapping = MappingProperty{Type: "float"}
 		case reflect.Bool:
 			fieldMapping = MappingProperty{Type: "boolean"}
 		case reflect.String:
 			fieldMapping = MappingProperty{Type: "text"}
+
+		case reflect.Slice:
+			//do not indicate slice, just map slice items as sub-items
+			subStructProperties, err := structMappingProperties(structField.Type.Elem())
+			if err != nil {
+				return nil, errors.Wrapf(err, "failed to map %s.%s", structType, structField.Name)
+			}
+			fieldMapping = MappingProperty{
+				Properties: subStructProperties,
+			}
+
 		default:
 			if structField.Type == reflect.TypeOf(time.Now()) {
 				fieldMapping = MappingProperty{Type: "date"}