Search code examples
mongodbgomongo-go

How to create a text index for nested fields that have the same name


I am trying to create a compound text index on 2 nested fields that have the same name. The reason why I am trying to do this is so that I can perform full text search using mongo on both fields.

data structure example

{
    "createdAt": "2023-01-20T18:39:45.551Z",
    "id": "63cadff13fc409d0b026f219",
    "userId": "63c13a9ba4c921b78e7d1a3a",
    "question": {
        "statement": "what is the atomic number of potassium?",
        "fileUrl": "http://localhost:4000/media/90152d8363424e688ad6e9505194a818.jpg",
        "mediaType": 2
    },
    "answer": {
        "statement": "19"
    }
}

as you can see from the example, both question and answer have the same nested field statement. I am trying to have a text index on both question and answer statements

what i tried to do

    textSearchIndexModel := mongo.IndexModel{
        Keys: bson.D{
            {Value: "question.statement", Key: "text"},
            {Value: "answer.statement", Key: "text"},
        },
        Options: options.Index().SetName("textSearchIndex"),
    }

this did not work and produced this error:

Failed to create index for flashcard collection:....caused by :: 
The field 'text' appears multiple times in the index key pattern
  • Is there a way to do this?
  • Is my approach a correct approach for what I want to achieve?

p.s: if you are not familiar with go you can also upload how it would like on mongodb since the mapping to the mongodb go driver is pretty straight forward


Solution

  • Note that a collection can have at most one text index.

    If you know this and want to create a text index that covers both "question.statement" and "answer.statement", then that's doable.

    The error on your part is the index specification: bson.D represents a document, an ordered list of properties (name-value pairs). It's a slice of bson.E where bson.E is:

    type E struct {
        Key   string
        Value interface{}
    }
    

    The Key is the name of the property, Value is the value of that property. So you got it backwards, it should be:

    textSearchIndexModel := mongo.IndexModel{
        Keys: bson.D{
            {Key: "question.statement", Value: "text"},
            {Key: "answer.statement", Value: "text"},
        },
        Options: options.Index().SetName("textSearchIndex"),
    }