[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-vector-search-catalog-when-keywords-fail":3,"blog-nav-vector-search-catalog-when-keywords-fail":27},{"slug":4,"title":5,"description":6,"body":7,"category":8,"readTime":9,"tags":10,"coverImage":14,"coverImageAlt":15,"heroImage":16,"heroImageAlt":15,"metaTitle":17,"metaDescription":18,"ogImage":19,"noindex":20,"published":21,"publishAt":22,"sortOrder":23,"updatedAt":22,"status":24,"path":25,"bodyHtml":26},"vector-search-catalog-when-keywords-fail","Vector search in a catalog: when keywords are not enough","SKU lookup stays on a normal index. pgvector helps when the words in the query are not the words on the row, and only after you can show ten failed searches.","Laravel 13 documents semantic search: embeddings, vector queries, and PostgreSQL with pgvector. That is retrieval. It is not the same job as the [Laravel AI SDK article](\u002Fblog\u002Flaravel-13-ai-sdk-philippine-business-apps), which is drafts, triage, and extraction inside a workflow. Embeddings are mentioned there as a capability. This article is what happens when a person types a phrase and expects products.\n\nThe source for the feature is the [Laravel 13 release notes](https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Freleases). Use that, not a recap, when you check what the framework actually ships.\n\n## Keywords first\n\nExact codes, sizes, and names should hit an ordinary index. If the box fails on a SKU, a vector index will not save it. [Indexes](\u002Fblog\u002Fdatabase-indexing-slow-queries) are that fix. [PostgreSQL or MySQL](\u002Fblog\u002Fpostgresql-vs-mysql-for-applications) is the engine choice underneath it: Laravel’s pgvector path assumes PostgreSQL. Do not migrate off MySQL only to put this label on a small catalog.\n\n## Vectors when the words differ\n\nStaff type “quiet split type for a small bedroom.” The row says “1.0HP wall-mounted inverter.” Keyword search misses. A vector index can surface the row. You still store the source product, you still show that product, and you do not show a paragraph the model wrote instead of a price.\n\nEmbeddings go stale when the catalog changes. Rebuilding them is a [queue](\u002Fblog\u002Fqueues-work-outside-the-http-request) job, not work inside the search request. The search request reads the index that already exists.\n\n## When we leave it off\n\n- You cannot list ten real searches that return the wrong product.\n- The catalog is small enough that a person can scan it.\n- The goal is an “AI search” badge on the homepage.\n\nKeyword search remains the default. Vector search is an extra index of meaning, added when the examples prove the keyword index is the wrong tool.\n\n## Straight next step\n\n[Send ten searches that return the wrong product](\u002Fcontact), copied from what staff or customers actually typed. If those examples do not exist, the feature is early. We will say so.","Engineering",7,[11,12,13],"Search","PostgreSQL","Laravel","\u002Fimages\u002Fjournal\u002Fvector-search-catalog-when-keywords-fail-cover.webp?v=20261013b","Library shelves filled with books","\u002Fimages\u002Fjournal\u002Fvector-search-catalog-when-keywords-fail-hero.webp?v=20261013b","Vector Search When Keywords Are Not Enough | PrimeCode","When a Laravel catalog should add pgvector search, and when an ordinary index still answers the query.","\u002Fimages\u002Fjournal\u002Fvector-search-catalog-when-keywords-fail-og.webp?v=20261013b",false,true,"2026-10-30T01:00:00.000Z",58,"live","\u002Fblog\u002Fvector-search-catalog-when-keywords-fail","\u003Cp>Laravel 13 documents semantic search: embeddings, vector queries, and PostgreSQL with pgvector. That is retrieval. It is not the same job as the \u003Ca href=\"\u002Fblog\u002Flaravel-13-ai-sdk-philippine-business-apps\" rel=\"noopener noreferrer\">Laravel AI SDK article\u003C\u002Fa>, which is drafts, triage, and extraction inside a workflow. Embeddings are mentioned there as a capability. This article is what happens when a person types a phrase and expects products.\u003C\u002Fp>\n\u003Cp>The source for the feature is the \u003Ca href=\"https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Freleases\" rel=\"noopener noreferrer\">Laravel 13 release notes\u003C\u002Fa>. Use that, not a recap, when you check what the framework actually ships.\u003C\u002Fp>\n\u003Ch2>Keywords first\u003C\u002Fh2>\n\u003Cp>Exact codes, sizes, and names should hit an ordinary index. If the box fails on a SKU, a vector index will not save it. \u003Ca href=\"\u002Fblog\u002Fdatabase-indexing-slow-queries\" rel=\"noopener noreferrer\">Indexes\u003C\u002Fa> are that fix. \u003Ca href=\"\u002Fblog\u002Fpostgresql-vs-mysql-for-applications\" rel=\"noopener noreferrer\">PostgreSQL or MySQL\u003C\u002Fa> is the engine choice underneath it: Laravel’s pgvector path assumes PostgreSQL. Do not migrate off MySQL only to put this label on a small catalog.\u003C\u002Fp>\n\u003Ch2>Vectors when the words differ\u003C\u002Fh2>\n\u003Cp>Staff type “quiet split type for a small bedroom.” The row says “1.0HP wall-mounted inverter.” Keyword search misses. A vector index can surface the row. You still store the source product, you still show that product, and you do not show a paragraph the model wrote instead of a price.\u003C\u002Fp>\n\u003Cp>Embeddings go stale when the catalog changes. Rebuilding them is a \u003Ca href=\"\u002Fblog\u002Fqueues-work-outside-the-http-request\" rel=\"noopener noreferrer\">queue\u003C\u002Fa> job, not work inside the search request. The search request reads the index that already exists.\u003C\u002Fp>\n\u003Ch2>When we leave it off\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>You cannot list ten real searches that return the wrong product.\u003C\u002Fli>\n\u003Cli>The catalog is small enough that a person can scan it.\u003C\u002Fli>\n\u003Cli>The goal is an “AI search” badge on the homepage.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Keyword search remains the default. Vector search is an extra index of meaning, added when the examples prove the keyword index is the wrong tool.\u003C\u002Fp>\n\u003Ch2>Straight next step\u003C\u002Fh2>\n\u003Cp>\u003Ca href=\"\u002Fcontact\" rel=\"noopener noreferrer\">Send ten searches that return the wrong product\u003C\u002Fa>, copied from what staff or customers actually typed. If those examples do not exist, the feature is early. We will say so.\u003C\u002Fp>\n",{"prev":28,"related":45},{"slug":29,"title":30,"description":31,"category":8,"readTime":32,"tags":33,"coverImage":36,"coverImageAlt":37,"heroImage":38,"heroImageAlt":37,"metaTitle":39,"metaDescription":40,"ogImage":41,"noindex":20,"published":21,"publishAt":42,"sortOrder":43,"updatedAt":42,"status":24,"path":44},"approval-workflows-as-state-machines","Approval workflows are state machines, not email threads","Draft, submitted, approved, rejected, and expired are the states. Only a few moves are legal, and reject does not mean delete.",6,[34,35,13],"Workflow","Domain","\u002Fimages\u002Fjournal\u002Fapproval-workflows-as-state-machines-cover.webp?v=20261013b","Printed form on a clipboard beside a laptop","\u002Fimages\u002Fjournal\u002Fapproval-workflows-as-state-machines-hero.webp?v=20261013b","Approval Workflows as State Machines | PrimeCode","How a quotation or purchase approval should move through explicit states, with one audit trail and no silent overwrites.","\u002Fimages\u002Fjournal\u002Fapproval-workflows-as-state-machines-og.webp?v=20261013b","2026-10-28T01:00:00.000Z",57,"\u002Fblog\u002Fapproval-workflows-as-state-machines",[46,48,65],{"slug":29,"title":30,"description":31,"category":8,"readTime":32,"tags":47,"coverImage":36,"coverImageAlt":37,"heroImage":38,"heroImageAlt":37,"metaTitle":39,"metaDescription":40,"ogImage":41,"noindex":20,"published":21,"publishAt":42,"sortOrder":43,"updatedAt":42,"status":24,"path":44},[34,35,13],{"slug":49,"title":50,"description":51,"category":8,"readTime":9,"tags":52,"coverImage":56,"coverImageAlt":57,"heroImage":58,"heroImageAlt":57,"metaTitle":59,"metaDescription":60,"ogImage":61,"noindex":20,"published":21,"publishAt":62,"sortOrder":63,"updatedAt":62,"status":24,"path":64},"one-database-many-branches-row-scope","One database, many branches: scope rows, do not split the system","A second site is a branch column, not a second app. Stock and schedules stay scoped. Queries, exports, and jobs must all carry that scope.",[53,54,55],"Architecture","Database","Branches","\u002Fimages\u002Fjournal\u002Fone-database-many-branches-row-scope-cover.webp?v=20261013b","Open sign hanging in a shop window","\u002Fimages\u002Fjournal\u002Fone-database-many-branches-row-scope-hero.webp?v=20261013b","One Database, Many Branches | PrimeCode","How a business system scopes stock and schedules to a branch without cloning the database or standing up microservices.","\u002Fimages\u002Fjournal\u002Fone-database-many-branches-row-scope-og.webp?v=20261013b","2026-10-26T01:00:00.000Z",56,"\u002Fblog\u002Fone-database-many-branches-row-scope",{"slug":66,"title":67,"description":68,"category":8,"readTime":32,"tags":69,"coverImage":72,"coverImageAlt":73,"heroImage":74,"heroImageAlt":73,"metaTitle":75,"metaDescription":76,"ogImage":77,"noindex":20,"published":21,"publishAt":78,"sortOrder":79,"updatedAt":78,"status":24,"path":80},"sanctum-cookie-sessions-vs-bearer-tokens","Cookie sessions or bearer tokens for a Nuxt and Laravel app","A first-party Nuxt app should use a Sanctum cookie session. Bearer tokens belong to mobile apps and other clients, and they must be revocable.",[70,13,71],"Auth","Nuxt","\u002Fimages\u002Fjournal\u002Fsanctum-cookie-sessions-vs-bearer-tokens-cover.webp?v=20261013b","Person at a laptop in an office","\u002Fimages\u002Fjournal\u002Fsanctum-cookie-sessions-vs-bearer-tokens-hero.webp?v=20261013b","Cookie Sessions vs Bearer Tokens | PrimeCode","When a Nuxt and Laravel app should use Sanctum cookie sessions, and when a bearer token is the right client.","\u002Fimages\u002Fjournal\u002Fsanctum-cookie-sessions-vs-bearer-tokens-og.webp?v=20261013b","2026-10-23T01:00:00.000Z",55,"\u002Fblog\u002Fsanctum-cookie-sessions-vs-bearer-tokens"]