Optionalprovider: IMetadataProviderOptional request-scoped metadata provider; see VectorBase constructor.
Protected_Provider-aware metadata access: returns the explicit provider when one was supplied
(constructor or Provider setter), otherwise the global default. All metadata
operations in this class hierarchy go through this getter so a bound instance never
leaks onto the global provider.
Optional metadata provider override. Pass the provider to the constructor (preferred)
or set instance.Provider = providerToUse before invoking helper methods in
multi-provider contexts. Setting it rebinds the internal RunView instance so view
execution rides the same provider. Falls back to the global default when unset.
ProtectedProviderReturns the active metadata provider — explicit override (via this.Provider = ...)
if set, otherwise the global default. Provided as ProviderToUse for backward
compatibility with code paths that referenced this name before the base class
standardized on the Provider getter/setter.
ProtectedaddAdds configured display fields with type-aware storage: numeric SQL types stay
numeric, date fields can convert to epoch seconds/milliseconds via storeAs,
uniqueidentifier values are lowercase-normalized, and long strings are truncated.
OptionalmetadataConfig: EntityDocumentMetadataConfigProtectedaddAdds EntityIcon: opt-out by default, opt-in under the 'explicit' strategy.
ProtectedaddAdds the system-injected RecordID / Entity / TemplateID keys — omitted entirely under the 'explicit' strategy, where metadata contains only configured fields.
ProtectedaddAdds __mj_UpdatedAt for recency sorting: opt-out by default, opt-in under the 'explicit' strategy.
ProtectedBuildBuilds a SQL filter from composite keys. Values are sanitized to prevent SQL injection.
ProtectedBuildBuild the SQL filter to select records that are in the given list. For single PK entities, uses a simple IN clause. For composite PK entities, uses an EXISTS clause that concatenates PK columns to match the RecordID format.
ProtectedBuildProtectedbuildBuild the vector metadata object for one embedding item.
Under 'all' / 'include' / 'exclude' strategies (the historical behavior), the system keys RecordID / Entity / TemplateID are always present, and EntityIcon / __mj_UpdatedAt default ON (opt-out via includeEntityIcon / includeUpdatedAt).
Under the 'explicit' strategy, metadata contains EXACTLY the configured fields: no system keys, and EntityIcon / __mj_UpdatedAt flip to opt-in (default false).
protected and decomposed into focused add*Metadata steps (each also protected)
so a subclass can override just the piece it cares about — e.g. a custom EntityIcon
resolution, or different chunk-aware display-field handling — without having to
reimplement this whole method.
OptionalmetadataConfig: EntityDocumentMetadataConfigProtectedCanReturns true when PageRecordsByEntityID can serve the given entity via
keyset (seek) pagination — i.e. the entity has a single-column PK on a comparable
type. Callers iterating large tables should consult this and pass AfterKey when true.
Refreshes the EntityDocumentCache and configures the AIEngine and TemplateEngineServer
If true, the cache and enginges will be refreshed even if it is already loaded
OptionalcontextUser: UserInfoThe context user to use to refresh the cache and configure the engines
This method will create a default Entity Document for the given entityID, vectorDatabase, and AIModel
ProtectedCreateReturns active Entity Documents for vectorization. Defaults to the
Record Duplicate document type for back-compat with the historical use
case (duplicate detection); pass entityDocumentType to target a different
type (e.g. 'Search' for the search-tier vector pool that backs
Provider.SearchEntity).
When multiple active EntityDocuments exist for the same entity (e.g. for different content variants), only the first row encountered is kept — the one-doc-per-entity restriction matches what existing vectorize callers already expect.
Cache source. Reads from KnowledgeHubMetadataEngine's cached
EntityDocuments array (already loaded by Config() above) — no fresh
RunView. The denormalized Type and Entity columns are available on
the cached rows, so the type and entity filters are pure client-side
predicates.
Empty result is not an error. When no Active documents match (none configured
yet, or all inactive), this returns an empty array — it does NOT throw. An unknown/
misspelled entityDocumentType is surfaced as a LogStatus warning, still returning
[]. Callers treat the empty case as "nothing to do" (e.g. VectorizeEntityAction
reports NO_DOCUMENTS success), so the unattended daily Entity Vector Sync job isn't
flagged as failed on a fresh DB with no Search documents.
OptionalentityNames: string[]If provided, only Entity Documents for the specified entities will be returned.
Name of the EntityDocumentType to filter by. Defaults to 'Record Duplicate'. Pass 'Search' for the search-tier pool.
Active, de-duped-per-entity Entity Documents of the given type; [] when none match.
ProtectedGetOptionalid: stringOptionalContextUser: UserInfoProtectedGetProtectedGetOptionalrecordIDs: CompositeKey[]ProtectedGetProtectedGetProtectedGetOptionalid: stringProtectedGetOptionalcreateDocumentIfNotFound: booleanProtectedPageProtectedResolveResolves the API key for a vector database provider. Checks the Credential Engine
first (if VectorDatabase.CredentialID is set), then falls back to the legacy
environment variable AI_VENDOR_API_KEY__
ProtectedRunProtectedSaveSaving an Entity in any vector related package needs the CurrentUser property to be set on the entity So this is a simple wrapper to set it before saving
ProtectedUpsertCreates or updates Entity Record Documents for a batch of source records.
Reads are batched + parallel, saves are per-record. Previously each record did its own
RunView to find its existing ERD — an N+1 read storm (~1 query per source record)
that dominated the upsert phase and tripped the sequential/duplicate-RunView telemetry.
Here we group by (EntityID, EntityDocumentID) and issue the existence checks for ALL groups
in a SINGLE RunViews batch (one round trip, run in parallel) with a RecordID IN (…) filter
per group, map the results by RecordID, then find-or-create + Save() each record (the
per-record Save() is inherent to the BaseEntity contract). Grouping is usually a single read
within one entity's pipeline; a mixed batch produces several views, now executed together.
ProtectedUpsertCreates or updates the Entity Record Document for a single source record. Thin back-compat wrapper over UpsertEntityRecordDocumentBatch; the pipeline uses the batch path directly to avoid an N+1 read per record.
ProtectedValidateThis method is resposnible for determining if the template(s) given have aligned parameters, meaning they don't have overlapping parameter names that have different meanings. It is okay for scenarios where there are > 1 template in use for a message to have different parameter names, but if they have the SAME parameter names they must not have different settings.
OptionalcontextUser: UserInfo
Class that specializes in vectorizing entities using embedding models and upserting them into Vector Databases