Problem · String

Text Embedding and Vector Search

Learn this problem
MediumNike, Inc. logoNike, Inc.FULLTIMEPHONE SCREEN

Problem statement

Process a finite batch of operations against an in-memory text index. You are given equal-length arrays operations, ids, texts, and ks. Handle each index in order:

  • "UPSERT" creates or replaces the record named by ids[i] with texts[i]. Ignore ks[i].
  • "SEARCH" uses texts[i] as a query. Ignore ids[i] and return the IDs of the ks[i] most similar records currently in the index.

Embedding and ranking

Lowercase each text and split it on spaces. Its term-frequency embedding contains the count of every token, normalized to Euclidean length 1. Rank records by cosine similarity to the query embedding.

Break equal-similarity ties by ascending record ID. Zero-similarity records remain eligible when they are needed to return exactly k IDs.

Return one row for every operation in input order. An UPSERT row is empty. A SEARCH row contains its ranked record IDs.

Function

processVectorIndex(operations: String[], ids: String[], texts: String[], ks: int[]) → String[][]

Examples

Example 1

operations = ["UPSERT","UPSERT","SEARCH"]ids = ["shoe-a","shoe-b",""]texts = ["red running shoe","blue hiking boot","red shoe"]ks = [0,0,2]return = [[],[],["shoe-a","shoe-b"]]

The first two operations return empty rows. The query shares two tokens with shoe-a and none with shoe-b, so the records appear in that order.

Example 2

operations = ["UPSERT","UPSERT","SEARCH","UPSERT","SEARCH"]ids = ["a","b","","a",""]texts = ["air zoom shoe","air trail shoe","air shoe","basketball court","air shoe"]ks = [0,0,2,0,2]return = [[],[],["a","b"],[],["b","a"]]

The first query gives both records the same similarity, so ID order puts a first. Replacing a removes its former terms; the second query ranks b first and includes zero-similarity a second.

Example 3

operations = ["UPSERT","UPSERT","UPSERT","SEARCH"]ids = ["a","b","c",""]texts = ["run run shoe","run shoe shoe","jacket","run run"]ks = [0,0,0,2]return = [[],[],[],["a","b"]]

Term frequency matters: record a has two occurrences of run, so its normalized embedding is closer to the repeated-token query than record b.

Constraints

  • 1 <= operations.length <= 500.
  • operations.length == ids.length == texts.length == ks.length.
  • Every operation is exactly "UPSERT" or "SEARCH".
  • Every text contains 1 to 30 non-empty ASCII-letter tokens separated by single spaces, with no leading or trailing space.
  • For UPSERT, ids[i] contains 1 to 20 lowercase ASCII letters, digits, or hyphens, and ks[i] == 0.
  • For SEARCH, ids[i] is empty and 1 <= ks[i] <= the number of records currently stored.
  • At most 500 distinct records are stored at once.

More Nike, Inc. problems

drafts saved locally
public String[][] processVectorIndex(String[] operations, String[] ids, String[] texts, int[] ks) {
    // Write your code here.
}
operations["UPSERT","UPSERT","SEARCH"]
ids["shoe-a","shoe-b",""]
texts["red running shoe","blue hiking boot","red shoe"]
ks[0,0,2]
expected[["", "", "shoe-a", "shoe-b"]]
checking account