Weaviate
Weaviate is an open source vector database that stores both objects and vectors, allowing for combining vector search with structured filtering.
LangChain connects to Weaviate via the weaviate-ts-client package, the official Typescript client for Weaviate.
LangChain inserts vectors directly to Weaviate, and queries Weaviate for the nearest neighbors of a given vector, so that you can use all the LangChain Embeddings integrations with Weaviate.
Setup
Weaviate has their own standalone integration package with LangChain, accessible via @langchain/weaviate on NPM!
- npm
- Yarn
- pnpm
npm install @langchain/weaviate @langchain/openai @langchain/community
yarn add @langchain/weaviate @langchain/openai @langchain/community
pnpm add @langchain/weaviate @langchain/openai @langchain/community
You'll need to run Weaviate either locally or on a server, see the Weaviate documentation for more information.
Usage, insert documents
/* eslint-disable @typescript-eslint/no-explicit-any */
import weaviate, { ApiKey } from "weaviate-ts-client";
import { WeaviateStore } from "@langchain/weaviate";
import { OpenAIEmbeddings } from "@langchain/openai";
export async function run() {
  // Something wrong with the weaviate-ts-client types, so we need to disable
  const client = (weaviate as any).client({
    scheme: process.env.WEAVIATE_SCHEME || "https",
    host: process.env.WEAVIATE_HOST || "localhost",
    apiKey: new ApiKey(process.env.WEAVIATE_API_KEY || "default"),
  });
  // Create a store and fill it with some texts + metadata
  await WeaviateStore.fromTexts(
    ["hello world", "hi there", "how are you", "bye now"],
    [{ foo: "bar" }, { foo: "baz" }, { foo: "qux" }, { foo: "bar" }],
    new OpenAIEmbeddings(),
    {
      client,
      indexName: "Test",
      textKey: "text",
      metadataKeys: ["foo"],
    }
  );
}
API Reference:
- WeaviateStore from @langchain/weaviate
- OpenAIEmbeddings from @langchain/openai
Usage, query documents
/* eslint-disable @typescript-eslint/no-explicit-any */
import weaviate, { ApiKey } from "weaviate-ts-client";
import { WeaviateStore } from "@langchain/weaviate";
import { OpenAIEmbeddings } from "@langchain/openai";
export async function run() {
  // Something wrong with the weaviate-ts-client types, so we need to disable
  const client = (weaviate as any).client({
    scheme: process.env.WEAVIATE_SCHEME || "https",
    host: process.env.WEAVIATE_HOST || "localhost",
    apiKey: new ApiKey(process.env.WEAVIATE_API_KEY || "default"),
  });
  // Create a store for an existing index
  const store = await WeaviateStore.fromExistingIndex(new OpenAIEmbeddings(), {
    client,
    indexName: "Test",
    metadataKeys: ["foo"],
  });
  // Search the index without any filters
  const results = await store.similaritySearch("hello world", 1);
  console.log(results);
  /*
  [ Document { pageContent: 'hello world', metadata: { foo: 'bar' } } ]
  */
  // Search the index with a filter, in this case, only return results where
  // the "foo" metadata key is equal to "baz", see the Weaviate docs for more
  // https://weaviate.io/developers/weaviate/api/graphql/filters
  const results2 = await store.similaritySearch("hello world", 1, {
    where: {
      operator: "Equal",
      path: ["foo"],
      valueText: "baz",
    },
  });
  console.log(results2);
  /*
  [ Document { pageContent: 'hi there', metadata: { foo: 'baz' } } ]
  */
}
API Reference:
- WeaviateStore from @langchain/weaviate
- OpenAIEmbeddings from @langchain/openai
Usage, maximal marginal relevance
You can use maximal marginal relevance search, which optimizes for similarity to the query AND diversity.
/* eslint-disable @typescript-eslint/no-explicit-any */
import weaviate, { ApiKey } from "weaviate-ts-client";
import { WeaviateStore } from "@langchain/weaviate";
import { OpenAIEmbeddings } from "@langchain/openai";
export async function run() {
  // Something wrong with the weaviate-ts-client types, so we need to disable
  const client = (weaviate as any).client({
    scheme: process.env.WEAVIATE_SCHEME || "https",
    host: process.env.WEAVIATE_HOST || "localhost",
    apiKey: new ApiKey(process.env.WEAVIATE_API_KEY || "default"),
  });
  // Create a store for an existing index
  const store = await WeaviateStore.fromExistingIndex(new OpenAIEmbeddings(), {
    client,
    indexName: "Test",
    metadataKeys: ["foo"],
  });
  const resultOne = await store.maxMarginalRelevanceSearch("Hello world", {
    k: 1,
  });
  console.log(resultOne);
}
API Reference:
- WeaviateStore from @langchain/weaviate
- OpenAIEmbeddings from @langchain/openai
Usage, delete documents
/* eslint-disable @typescript-eslint/no-explicit-any */
import weaviate, { ApiKey } from "weaviate-ts-client";
import { WeaviateStore } from "@langchain/weaviate";
import { OpenAIEmbeddings } from "@langchain/openai";
export async function run() {
  // Something wrong with the weaviate-ts-client types, so we need to disable
  const client = (weaviate as any).client({
    scheme: process.env.WEAVIATE_SCHEME || "https",
    host: process.env.WEAVIATE_HOST || "localhost",
    apiKey: new ApiKey(process.env.WEAVIATE_API_KEY || "default"),
  });
  // Create a store for an existing index
  const store = await WeaviateStore.fromExistingIndex(new OpenAIEmbeddings(), {
    client,
    indexName: "Test",
    metadataKeys: ["foo"],
  });
  const docs = [{ pageContent: "see ya!", metadata: { foo: "bar" } }];
  // Also supports an additional {ids: []} parameter for upsertion
  const ids = await store.addDocuments(docs);
  // Search the index without any filters
  const results = await store.similaritySearch("see ya!", 1);
  console.log(results);
  /*
  [ Document { pageContent: 'see ya!', metadata: { foo: 'bar' } } ]
  */
  // Delete documents with ids
  await store.delete({ ids });
  const results2 = await store.similaritySearch("see ya!", 1);
  console.log(results2);
  /*
  []
  */
  const docs2 = [
    { pageContent: "hello world", metadata: { foo: "bar" } },
    { pageContent: "hi there", metadata: { foo: "baz" } },
    { pageContent: "how are you", metadata: { foo: "qux" } },
    { pageContent: "hello world", metadata: { foo: "bar" } },
    { pageContent: "bye now", metadata: { foo: "bar" } },
  ];
  await store.addDocuments(docs2);
  const results3 = await store.similaritySearch("hello world", 1);
  console.log(results3);
  /*
  [ Document { pageContent: 'hello world', metadata: { foo: 'bar' } } ]
  */
  // delete documents with filter
  await store.delete({
    filter: {
      where: {
        operator: "Equal",
        path: ["foo"],
        valueText: "bar",
      },
    },
  });
  const results4 = await store.similaritySearch("hello world", 1, {
    where: {
      operator: "Equal",
      path: ["foo"],
      valueText: "bar",
    },
  });
  console.log(results4);
  /*
  []
  */
}
API Reference:
- WeaviateStore from @langchain/weaviate
- OpenAIEmbeddings from @langchain/openai