I’m trying to perform a vector embedding search with MongoDB Atlas Search.
I’m searching for clothes which I store in the Garment collection of my database. This is my Garment Schema:
const GarmentSchema = new Schema({
name: {
type: String,
required: true,
},
brand: {
type: String,
required: true,
},
colors: {
type: [String],
required: true,
},
category: {
type: String,
required: true,
},
image_url: {
type: String,
},
user: {
type: Schema.Types.ObjectId,
ref: "User",
},
embedding: {
type: [Number],
required: true,
},
createdAt: {
type: String,
required: true,
index: true,
},
});
This is based on the example MongoDB gives us for vector search, as it applies to my schema:
const matchingGarments = await collection.aggregate([
{
$search: {
index: "default",
knnBeta: {
vector: embedding,
path: "embedding",
k: 5,
},
},
},
])
.toArray();
However, I would like to query by “top” or “bottom” so I added the match field, and Atlas search requires that if using knnBeta the $search query be first (or it returns an error) so I wrote it like this:
const matchingGarments = await collection
.aggregate([
{
$search: {
index: "default",
knnBeta: {
vector: embedding,
path: "embedding",
k: 5,
},
},
},
{
$match: {
category,
},
},
])
.toArray();
However, I tested it to realize that it doesn’t actually make a difference because it’s still querying the top 5 results and then splitting them up based on the category so I could end up with 4 tops and 1 bottom regardless of the category I specify. I would like to get the top 5 bottoms that match when I input the category as “bottom” and the top 5 tops when I input “top”.
Is there any way to do this? Any input is really appreciated.