Home > Software engineering >  How to create a text index for nested fields that have the same name
How to create a text index for nested fields that have the same name

Time:01-22

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

CodePudding user response:

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"),
}
  • Related