typesense / typesense

Open Source alternative to Algolia + Pinecone and an Easier-to-Use alternative to ElasticSearch ⚡ 🔍 ✨ Fast, typo tolerant, in-memory fuzzy Search Engine for building delightful search experiences

Home Page:https://typesense.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Alias names are not reserved if the collection it's pointing at doesn't exist

dkrsorenson opened this issue · comments

Description

If I create an alias in Typesense that points at a collection that doesn't exist yet, I'm still able to create a collection using the same name as the alias name.

Steps to reproduce

  1. Create an alias named tests pointing at non-existent collection tests_v1
  2. Create a collection named tests
  3. You can see that the alias tests and the collection tests both exist

In my instance it was named contacts. In the images here you can see that I have an alias named contacts and a collection named contacts (sorry the schema is cut off but it is a collection).
image
image

I also tried to write a script to showcase the flow of creating the alias then the collection with the same name. You would just need to set up a Typesense client and try to run the script (sorry if it doesn't work out of the box).

import { CollectionCreateSchema } from 'typesense/lib/Typesense/Collections';
import { Client } from 'typesense';

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on('close', () => {
  process.exit(0);
});

// empty client - need to set for the script
let typesenseClient;

async function test(): Promise<void> {
  const aliasName = 'tests';
  const collectionName = 'tests_v1';

  // create the alias first
  // tests_v1 should not exist bc we haven't created a collection with that name
  try {
    let aliased_collection = {
      collection_name: collectionName,
    };

    const alias = await typesenseClient.aliases().upsert(aliasName, aliased_collection);

    console.log(`Alias ${aliasName} created/updated!`);
    console.log(alias);
  } catch (err) {
    console.log(`Error creating/updating alias ${aliasName}`);
    console.log(err);
  }

  console.log('');

  try {
    // intentionally using the alias name here to show the issue
    // it'll still let me create the collection with the same name
    let contactsSchema: CollectionCreateSchema = {
      name: aliasName,
      enable_nested_fields: true,
      fields: [{ name: 'account_id', type: 'string', optional: true, sort: false }],
      token_separators: ['+', '-', '@', '.'],
    };

    const collection = await typesenseClient.collections(aliasName).retrieve();
    if (collection) {
      console.log(`Collection ${aliasName} already exists...`);
      return;
    }
  } catch (err) {
    if (err.httpStatus !== 404) {
      throw err;
    }
  }

  try {
    console.log(`Creating ${aliasName} collection...`);
    const collection = await typesenseClient.collections().create(contactsSchema as any);
    console.log(`Collection ${aliasName} created!`);
    console.log(collection);
  } catch (err) {
    throw err;
  }
}

async function run() {
  // set the typesense client
  typesenseClient = ....
  await test();
}

run().catch(console.error);

Expected Behavior

I would expect it to reserve the name being used by the alias despite whether or not the collection exists yet.

I also am not sure if it's intentional to allow for aliases to point at collections that don't exist. If it's not, changing that behavior could also help with addressing this (because I wouldn't be able to create the alias in this case).

Actual Behavior

You can have an alias and a collection using the same name when the alias is created with or pointing at a collection that doesn't exist.

Metadata

Typesense Version: v26.0.rc40

OS:

I also am not sure if it's intentional to allow for aliases to point at collections that don't exist.

This is intentional. We don't want to couple the use of alias with collections. Since this behavior already exists, we can't change this because it will break systems that depend on this.

I also am not sure if it's intentional to allow for aliases to point at collections that don't exist.

This is intentional. We don't want to couple the use of alias with collections. Since this behavior already exists, we can't change this because it will break systems that depend on this.

@kishorenc So, is the rest of the scenario described in the ticket expected then? You should be able to create a collection with the same name that an alias is using? So I can have an alias with the name "contacts" and a collection with the name "contacts" at the same time? How would Typesense know which to reference?

We check for actual collection first and if that's not found we look for an alias.