typesense / typesense/typesense-go

typesense automatic field duplication in schema when using object[]

Open
#223 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
319
Forks
73
PR merge metrics
No merged PRs in 30d

Description

this is my product schema and i didnt created any duplicated fields in it even typesense doenst allow it .

but when i see collection schema after inserting 1 doc it automatically created duplicates nested fields . why is this weird behavior or please tell me if i am doing something wrong
duplicated fields are of {Name: "parent_category_ids", Type: "object[]"},

Product Collection Schema

`productSchema := api.CollectionSchema{
Name: "products",
EnableNestedFields: pointer.True(),
Fields: []api.Field{
{Name: "id", Type: "string"},

		// Core product fields
		{Name: "title", Type: "string"},
		{Name: "description", Type: "string", Optional: pointer.True()},
		{Name: "points", Type: "int32", Sort: pointer.True(), Optional: pointer.True(), Facet: pointer.True()},
		{Name: "picture_url", Type: "object[]", Optional: pointer.True()},

		// Category hierarchy (very useful for browsing & faceting)
		{Name: "category_id", Type: "string", Facet: pointer.True(), Optional: pointer.True()},
		{Name: "category_name", Type: "string", Facet: pointer.True()},
		{Name: "category_slug", Type: "string", Facet: pointer.True(), Optional: pointer.True()},
		{Name: "parent_category_ids", Type: "object[]"},

		// Seller & status
		{Name: "seller_id", Type: "string", Facet: pointer.True(), Optional: pointer.True()},
		{Name: "seller_name", Type: "string", Optional: pointer.True()},
		{Name: "seller_location", Type: "string", Optional: pointer.True()},
		{Name: "is_active", Type: "bool", Facet: pointer.True()},

		// Location
		{Name: "location", Type: "geopoint", Sort: pointer.True(), Optional: pointer.True()},
		{Name: "country", Type: "string", Facet: pointer.True(), Optional: pointer.True()},
		{Name: "city", Type: "string", Facet: pointer.True(), Optional: pointer.True()},
		{Name: "state", Type: "string", Facet: pointer.True(), Optional: pointer.True()},

		// Pricing (important for range filtering & faceting)
		{Name: "min_price", Type: "float", Facet: pointer.True(), Sort: pointer.True(), RangeIndex: pointer.True(), Optional: pointer.True()},
		{Name: "max_price", Type: "float", Facet: pointer.True(), Sort: pointer.True(), RangeIndex: pointer.True(), Optional: pointer.True()},

		// 🔥 Main field for all dynamic attributes (from your product_attributes table)
		{Name: "attributes", Type: "string[]", Facet: pointer.True(), Optional: pointer.True()},
		// Stored as: ["Material:Stainless Steel", "GSM:180", "Power:7.5 HP", "Voltage:415V", ...]

		// Optional: Store raw attributes for easy Product Detail Page (PDP) display
		{Name: "raw_attributes", Type: "object", Index: pointer.False(), Optional: pointer.True()},

		// Timestamps for sorting (newest, etc.)
		{Name: "created_at", Type: "int64", Sort: pointer.True()},
	},
	DefaultSortingField: pointer.String("created_at"),
}`

Product Schema after inserting 1 doc
{ "created_at": 1775283607, "curation_sets": [], "default_sorting_field": "", "enable_nested_fields": true, "fields": [ { "facet": true, "index": true, "infix": false, "locale": "", "name": "country", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "city", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "state", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "min_price", "optional": true, "range_index": true, "sort": true, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "float" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "max_price", "optional": true, "range_index": true, "sort": true, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "float" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "attributes", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": false, "index": false, "infix": false, "locale": "", "name": "raw_attributes", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "object" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "created_at", "optional": false, "sort": true, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "int64" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.slug", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.position", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "int64[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.name", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.id", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "location", "optional": true, "sort": true, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "geopoint" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "is_active", "optional": false, "sort": true, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "bool" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "seller_location", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "seller_name", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "seller_id", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids", "optional": false, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "object[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.id", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.slug", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.position", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "int64[]" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "parent_category_ids.name", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string[]" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "category_slug", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "category_name", "optional": false, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "category_id", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": true, "index": true, "infix": false, "locale": "", "name": "points", "optional": true, "sort": true, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "int32" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "description", "optional": true, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" }, { "facet": false, "index": true, "infix": false, "locale": "", "name": "title", "optional": false, "sort": false, "stem": false, "stem_dictionary": "", "store": true, "truncate_len": 100, "type": "string" } ], "name": "products", "num_documents": 1, "symbols_to_index": [], "synonym_sets": [], "token_separators": [] }

Doc that i inserted

[ { "attributes": [ "Color:Blue" ], "category_name": "Keypad Mobile", "category_slug": "keypad-mobile", "created_at": 1775288386, "description": "Good Phone", "id": "c5b821e5-2b16-477d-953f-ee2faad03559", "is_active": true, "min_price": 2000, "parent_category_ids": [ { "id": "8ebf6ffb-61cb-4588-ac46-99ae8f0c3075", "name": "Electronics & Appliances", "position": 0, "slug": "electronics-&-appliances" }, { "id": "102a1f22-2afa-40b9-b6bc-efd212f72df3", "name": "Phones", "position": 1, "slug": "phones" } ], "raw_attributes": { "Color": "Blue" }, "seller_id": "1", "title": "Nokia 3310 Body Cover " } ]

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the provided Go CollectionSchema with EnableNestedFields enabled, insert one document, and compare the collection schema before and after. Confirm whether parent_category_ids and its nested fields are duplicated, then document the expected schema behavior or a minimal failing case.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.