按给定字段搜索嵌套对象的数组

I have the following structure of the Room object.

type Room struct {
Id          bson.ObjectId       `json:"id" bson:"_id,omitempty"`
Title       string              `json:"title" bson:"title"`
Description string              `json:"description" bson:"description,omitempty"`
Type        string              `json:"type" bson:"type,omitempty"`
AdminId     bson.ObjectId       `json:"admin_id" bson:"admin_id"`
CreatedOn   time.Time           `json:"created_on" bson:"created_on"`
Messages    []Message           `json:"messages" bson:"messages,omitempty"`}

Where Messages is nested array of objects that has the following structure

type Message struct {
Id      bson.ObjectId   `json:"id" bson:"_id,omitempty"`
Text        string          `json:"text" bson:"text"`
Author      Author          `json:"author" bson:"author"`
CreatedOn   time.Time   `json:"createdon" bson:"created_on"`
Reply       []Message   `json:"reply" bson:"reply,omitempty"`}

I want to perform the search query by the messages in the collection of rooms. I tried using "$in" but I did not help me.

Moreover, I have to search elements by matching values. I can do this using bson regular expressions.

&bson.RegEx{Pattern: textToFind, Options: "i"}

Summing up I need to search messages by the Text field in the nested object in the Room document.

P.S. Sorry for possible mistakes, English is not my native language.

UPDATE

Basically, I want to find all the messages in the given room that contains some substring. For example, search for all messages in the room (chat) 'A' that contains 'some text' substring.

You can try the below mongo shell aggregation pipeline.

$matches on some room attribute (ex _id).

$unwind messages( transform messages array into object ) in the room.

$matches on input regex against text field to filter messages.

$groups the message objects back into messages array.

$project to exclude _id and include only messages for output.

db.collection.aggregate(
{$match:{"_id":roomid}}, 
{$unwind:"$messages"}, 
{$match:{"messages.text": { $regex: /textToFind/i } }},
{$group:{_id:null,messages:{$push:"$messages"}}}, 
{$project:{_id:0, messages:1}})

Below is untested mgo equivalent.

match1 := bson.M{
    "$match": bson.M{
        "_id": roomid,
    },
}

unwind := bson.M{
    "$unwind": "$messages",
}

match2 := bson.M{
    "$match": bson.M{"messages.text": &bson.RegEx{Pattern: textToFind, Options: "i"}},
}

group := bson.M{
    "$group": bson.M{
        "_id": null,
        "messages": bson.M{
            "$push": "$messages",
        },
    },
}

project := bson.M{
    "$project":  bson.M{
        "_id": 0, 
        "messages":1,
    },
}

all := []bson.M{match1, unwind, match2, group, project}
pipe := collection.Pipe(all)

result := []bson.M{}
err := pipe.All(&result)