Member Junction
    Preparing search index...

    Class that specializes in vectorizing entities using embedding models and upserting them into Vector Databases

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    _currentUser: UserInfo
    _metadata: Metadata
    _runView: RunView
    EndTime: Date
    StartTime: Date

    Accessors

    • get CurrentUser(): UserInfo

      Returns UserInfo

    • set CurrentUser(user: UserInfo): void

      Parameters

      Returns void

    • get Metadata(): IMetadataProvider

      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.

      Returns IMetadataProvider

    • get Provider(): IMetadataProvider

      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.

      The fallback is the global provider itself, never the Metadata wrapper: consumers type-check what they get here (e.g. VectorDBBase.TryWireColocatedHost needs an IColocatedVectorHost), and the wrapper fails those checks.

      Returns IMetadataProvider

    • set Provider(value: IMetadataProvider): void

      Parameters

      Returns void

    • get ProviderToUse(): IMetadataProvider

      Returns 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.

      Returns IMetadataProvider

    • get RunView(): RunView

      Returns RunView

    Methods

    • Adds 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.

      Parameters

      Returns void

    • Adds __mj_UpdatedAt for recency sorting: opt-out by default, opt-in under the 'explicit' strategy.

      Parameters

      • metadata: Record<string, string | number | boolean>
      • record: Record<string, unknown>
      • metadataConfig: EntityDocumentMetadataConfig
      • explicit: boolean

      Returns void

    • Refuse a batch whose vectors are not the width the index accepts, before a single record is upserted.

      The Dimensions argument threaded into RunEmbedding is a request hint, not a contract: only some providers honour it (OpenAI's text-embedding-3-* family does), a local ONNX model is free to ignore it entirely, and nothing downstream ever compared what came back against what the index accepts. The consequences split by provider and both are bad:

      • A provider that enforces width rejects the upsert. Pinecone's own driver already knows this failure by name — see the comment on its CreateRecords catch block quoting "Vector dimension 1536 does not match the dimension of the index 512" — but it only learns it after the API round trip, per batch, for the whole run.
      • A provider that does not enforce width accepts them, and the index silently ends up holding vectors of two widths, which makes similarity search quietly meaningless.

      Throwing is deliberate and not per-record: every vector in the run comes from the same model, so a first-batch mismatch is a run-level misconfiguration. Continuing would spend the embedding budget on vectors that cannot be stored.

      Skipped when the index declares no width — see ResolveIndexDimensions for when that is legitimate.

      Parameters

      • embeddings: EmbeddingRunResult
      • expectedDimensions: number
      • embeddingModelAPIName: string
      • OptionalindexName: string

      Returns void

    • Builds a SQL filter from composite keys. Values are sanitized to prevent SQL injection.

      Parameters

      Returns string

    • Build 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.

      Parameters

      • entity: EntityInfo
      • listDetailsSchema: string
      • listId: string

      Returns string

    • The record-id string persisted to MJ: Entity Record Documents.RecordID and carried through the pipeline as __mj_recordID: the entity's actual primary key column(s) read off the row, in compact URL-segment form — the bare value for a single-column key (whatever that column is called), F1|v1||F2|v2 for a composite key. CompositeKey.FromURLSegment reads either form back, so a customer entity keyed by individual_id or (OrderID, LineNo) round-trips instead of being reduced to whichever column happens to be listed first.

      Parameters

      Returns string

    • Build 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.

      Parameters

      Returns Record<string, string | number | boolean>

    • Returns 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.

      Parameters

      • entityID: string | number

      Returns boolean

    • Refreshes the EntityDocumentCache and configures the AIEngine and TemplateEngineServer

      Parameters

      • forceRefresh: boolean

        If true, the cache and enginges will be refreshed even if it is already loaded

      • OptionalcontextUser: UserInfo

        The context user to use to refresh the cache and configure the engines

      Returns Promise<void>

    • Embeds one batch of rendered texts on the entity document's model. The ModelID pin keeps the vector index single-model: unpinned, the runner may answer from any Embeddings model. embeddingDimensions is the index's MJ: Vector Indexes.Dimensions (undefined for the model's native size).

      Parameters

      • texts: string[]
      • embeddingRunner: AIEmbeddingRunner
      • aiModelID: string
      • embeddingDimensions: number
      • templateName: string

      Returns Promise<EmbeddingRunResult>

    • Returns 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.

      Parameters

      • OptionalentityNames: string[]

        If provided, only Entity Documents for the specified entities will be returned.

      • entityDocumentType: string = 'Record Duplicate'

        Name of the EntityDocumentType to filter by. Defaults to 'Record Duplicate'. Pass 'Search' for the search-tier pool.

      Returns Promise<MJEntityDocumentEntity[]>

      Active, de-duped-per-entity Entity Documents of the given type; [] when none match.

    • Resolve the embedding model to generate vectors with.

      Pass an id wherever one exists. The width of an embedding is a property of the model, and the width an index accepts is fixed when the index is created, so which model this returns decides whether the vectors fit. The no-id branch cannot know that and is a last resort only.

      The no-id branch used to be a bare find() over AIEngine.Instance.Models, which BaseAIEngine.Config loads with no OrderBy and no IsActive filter. So it returned whichever Embeddings row the view happened to hand back first — a different model on a different database, or after an unrelated insert, and quite possibly a deactivated one. An arbitrary answer is worse than a wrong one: the same code produces different widths in different environments and nothing in the failure names the model that was chosen.

      It is now deterministic — active models first, then highest PowerRank, then name — and it says out loud which model it picked and that nobody asked for it.

      Parameters

      • Optionalid: string

      Returns MJAIModelEntityExtended

    • Resolve the embedding driver and vector-DB driver for an Entity Document.

      Parameters

      • entityDocumentID: string
      • OptionalcreateDocumentIfNotFound: boolean
      • OptionalvectorIndex: MJVectorIndexEntity

        When supplied, the embedding model is taken from the index (VectorIndex.EmbeddingModelID, a NOT NULL column) rather than from EntityDocument.AIModelID. The index's accepted width is fixed when the index is created and the width of an embedding is a property of the model, so the index is the only party whose opinion about the model can be right. EntityDocument.AIModelID is nullable, and when it is null this used to fall through to GetAIModel() with no argument — an arbitrary pick out of an unordered list, which is how an index ends up holding vectors of a width it never agreed to. A document that names a different model is reported rather than quietly honoured.

      Returns Promise<VectorEmeddingData>

    • The width this index accepts, or null when the index legitimately has none.

      Order of preference:

      1. VectorIndex.Dimensions when it is set. This is the operator's declaration, or the width MJVectorIndexEntityServer learned by probing the embedding model at create time and wrote back once the provider accepted the index. It is what the embedding request honours.
      2. Fallback only: the provider's own answer, via ListIndexes(), written back onto the row. This covers rows whose Dimensions is still null: indexes created before the create-time probe existed (the Knowledge Hub create-index form never set it, and the old write-back never ran when the provider call failed), and a row read before its detached provisioning has finished writing back. Refusing those rows outright would strand them, so the provider is asked first and the row is repaired.
      3. Refuse. An index whose width nobody can state cannot have embeddings checked against it, and that is the exact state the check exists to prevent.

      null is returned only for a driver that owns no index object (VectorDBBase.ManagesIndexes === false): for SimpleVectorServiceProvider the "index" is a logical pairing and the vectors live in MJ: Entity Record Documents.VectorJSON, a JSON column with no fixed width. There is nothing to check against and nothing to refuse.

      Parameters

      Returns Promise<number>

    • Type Parameters

      Parameters

      • entityName: string
      • extraFilter: string

      Returns Promise<T>

    • Saving 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

      Parameters

      Returns Promise<boolean>

    • Creates 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.

      Parameters

      Returns Promise<void>

    • This 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.

      Parameters

      Returns boolean