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.
$match
es on some room attribute (ex _id
).
$unwind
messages( transform messages
array into object ) in the room.
$match
es on input regex against text
field to filter messages
.
$group
s 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)