weaviate / typescript-client

Official Weaviate TypeScript Client
https://www.npmjs.com/package/weaviate-ts-client
BSD 3-Clause "New" or "Revised" License
57 stars 21 forks source link

[Question] How to convert code for collection creation from ts client v2 to new client v3 #149

Open michael-pont opened 1 week ago

michael-pont commented 1 week ago

I am having some troubles converting code from previous typescript client (v2) to new client (3.0.5). My confusion revolves around:

Here is the old "class"

import { WeaviateClass } from 'weaviate-ts-client'
import { CustomClassName } from '../types'

const className: CustomClassName = CustomClassName.SCOPED_ACCOUNT
export const ScopedAccountClass: WeaviateClass = {
  class: className,
  description: 'A class holding scoped information about an account',
  multiTenancyConfig: { enabled: true },
  vectorizer: 'text2vec-openai',
  moduleConfig: {
    'text2vec-openai': {
      model: 'text-embedding-3-small',
      dimensions: 1536,
      type: 'text',
      tokenization: 'word',
      vectorizeClassName: false,
    },
  },
  properties: [
    {
      name: 'accountId',
      description: 'The account id', // No cross-reference because querying from tenant to non tenant is not possible
      dataType: ['uuid'],
    },
    {
      name: 'crmAccountId',
      description:
        'CRM account identifier - we use this to link the account to our customers CRM',
      dataType: ['text'],
    },
    {
      name: 'teamId',
      description: 'Team ID - we use this as tenant identifier',
      dataType: ['uuid'],
    },
    {
      name: 'name',
      description:
        'Name of scoped account',
      dataType: ['text'],
    },
    {
      name: 'queryResponses',
      description:
        'The answers to the queries that are part of this enrichment request',
      dataType: ['object[]'],
      nestedProperties: [
        { dataType: ['text'], name: 'query' },
        { dataType: ['text'], name: 'customQueryId' },
        { dataType: ['text'], name: 'answer' },
        { dataType: ['text'], name: 'confidence' },
        { dataType: ['text'], name: 'explanation' },
        {
          name: 'sources',
          description: 'The sources of where the answer is found',
          dataType: ['object[]'],
          nestedProperties: [
            { dataType: ['text'], name: 'title' },
            { dataType: ['text'], name: 'link' },
            { dataType: ['boolean'], name: 'isVisitable' },
          ],
        },
      ],
    },
    {
      name: 'notes',
      description: 'Optional notes for the scoped account',
      dataType: ['text[]'],
      moduleConfig: {
        'text2vec-openai': {
          skip: false,
        },
      },
    },
    {
      name: 'enrichmentRequests',
      description:
        'Enrichment Requests - which enrichment requests are linked to this account',
      dataType: [`${CustomClassName.ENRICHMENT_REQUEST}[]`],
    },
    {
      name: 'customPropertyValues',
      description: 'Custom property values for this scoped account',
      dataType: [`${CustomClassName.CUSTOM_PROPERTY_VALUE}`],
    },
    {
      name: 'score',
      description: 'The score of the account',
      dataType: ['number'],
    },
    {
      name: 'originalUrl',
      description: 'Original input URL',
      dataType: ['text'],
      moduleConfig: {
        'text2vec-openai': {
          skip: true,
        },
      },
    },
  ],
}

Here is the new collection as I have defined it

import { CustomClassName } from '../types'
import { type CollectionConfigCreate } from 'weaviate-client'

const className: CustomClassName = CustomClassName.SCOPED_ACCOUNT
export const ScopedAccountClass: CollectionConfigCreate = {
  name: className,
  description: 'A class holding scoped information about an account',
  multiTenancy: {
    enabled: true,
  },
  vectorizers: [
    {
      name: 'text2vec-openai',
      properties: ['notes'],
      vectorIndex: {
        name: 'hnsw',
        config: {},
      },
      vectorizer: {
        name: 'text2vec-openai',
        config: {
          model: 'text-embedding-3-small',
          dimensions: 1536,
          type: 'text',
        },
      },
    },
  ],
  generative: {
    name: 'generative-openai',
    config: {
      model: 'gpt-3.5-turbo',
      temperatureProperty: 0,
    },
  },
  references: [
    {
      name: 'enrichmentRequests',
      description:
        'Enrichment Requests - which enrichment requests are linked to this account',
      targetCollection: CustomClassName.ENRICHMENT_REQUEST,
    },
    {
      name: 'customPropertyValues',
      description: 'Custom property values for this scoped account',
      targetCollection: CustomClassName.CUSTOM_PROPERTY_VALUE,
    },
  ],
  properties: [
    {
      name: 'accountId',
      description: 'The account id', // No cross-reference because querying from tenant to non tenant is not possible
      dataType: 'uuid',
    },
    {
      name: 'crmAccountId',
      description:
        'CRM account identifier - we use this to link the account to our customers CRM',
      dataType: 'text',
    },
    {
      name: 'teamId',
      description: 'Team ID - we use this as tenant identifier',
      dataType: 'uuid',
    },
    {
      name: 'name',
      description:
        'Name (honestly used for placeholder, as I want notes to be text[] and class creation will throw error)',
      dataType: 'text',
    },
    {
      name: 'queryResponses',
      description:
        'The answers to the queries that are part of this enrichment request',
      dataType: 'object[]',
      nestedProperties: [
        { dataType: 'text', name: 'query' },
        { dataType: 'text', name: 'customQueryId' },
        { dataType: 'text', name: 'answer' },
        { dataType: 'text', name: 'confidence' },
        { dataType: 'text', name: 'explanation' },
        {
          name: 'sources',
          description: 'The sources of where the answer is found',
          dataType: 'object[]',
          nestedProperties: [
            { dataType: 'text', name: 'title' },
            { dataType: 'text', name: 'link' },
            { dataType: 'boolean', name: 'isVisitable' },
          ],
        },
      ],
    },
    {
      name: 'notes',
      description: 'Optional notes for the scoped account',
      dataType: 'text[]',
    },
    {
      name: 'score',
      description: 'The score of the account',
      dataType: 'number',
    },
    {
      name: 'originalUrl',
      description: 'Original input URL',
      dataType: 'text',
      skipVectorization: true,
    },
  ],
}

Questions / Observations I had:

tsmith023 commented 1 week ago

Hi @michael-pont, thanks for diving straight into the new client and getting to grips with it!

To help your migration, here's how I would translate your .create() code to make use of the weaviate.configure object:

import { type CollectionConfigCreate } from '..'
import { CustomClassName } from '../types'
import weaviate from '../../index'

const className: CustomClassName = CustomClassName.SCOPED_ACCOUNT
export const ScopedAccountClass: CollectionConfigCreate = {
  name: className,
  description: 'A class holding scoped information about an account',
  multiTenancy: weaviate.configure.multiTenancy({ enabled: true }),
  vectorizers: weaviate.configure.vectorizer.text2VecOpenAI({
    sourceProperties: ['notes'],
    vectorIndexConfig: weaviate.configure.vectorIndex.hnsw(),
    model: 'text-embedding-3-small',
    dimensions: 1536,
    type: 'text',
  }),
  generative: weaviate.configure.generative.openAI({
    model: 'gpt-3.5-turbo',
    temperature: 0,
  }),
  references: [
    {
      name: 'enrichmentRequests',
      description:
        'Enrichment Requests - which enrichment requests are linked to this account',
      targetCollection: CustomClassName.ENRICHMENT_REQUEST,
    },
    {
      name: 'customPropertyValues',
      description: 'Custom property values for this scoped account',
      targetCollection: CustomClassName.CUSTOM_PROPERTY_VALUE,
    },
  ],
  properties: [
    {
      name: 'accountId',
      description: 'The account id', // No cross-reference because querying from tenant to non tenant is not possible
      dataType: 'uuid',
    },
    {
      name: 'crmAccountId',
      description:
        'CRM account identifier - we use this to link the account to our customers CRM',
      dataType: 'text',
    },
    {
      name: 'teamId',
      description: 'Team ID - we use this as tenant identifier',
      dataType: 'uuid',
    },
    {
      name: 'name',
      description:
        'Name (honestly used for placeholder, as I want notes to be text[] and class creation will throw error)',
      dataType: 'text',
    },
    {
      name: 'queryResponses',
      description:
        'The answers to the queries that are part of this enrichment request',
      dataType: 'object[]',
      nestedProperties: [
        { dataType: 'text', name: 'query' },
        { dataType: 'text', name: 'customQueryId' },
        { dataType: 'text', name: 'answer' },
        { dataType: 'text', name: 'confidence' },
        { dataType: 'text', name: 'explanation' },
        {
          name: 'sources',
          description: 'The sources of where the answer is found',
          dataType: 'object[]',
          nestedProperties: [
            { dataType: 'text', name: 'title' },
            { dataType: 'text', name: 'link' },
            { dataType: 'boolean', name: 'isVisitable' },
          ],
        },
      ],
    },
    {
      name: 'notes',
      description: 'Optional notes for the scoped account',
      dataType: 'text[]',
    },
    {
      name: 'score',
      description: 'The score of the account',
      dataType: 'number',
    },
    {
      name: 'originalUrl',
      description: 'Original input URL',
      dataType: 'text',
      skipVectorization: true,
    },
  ],
}