Search array of nested objects by given field

会有一股神秘感。 提交于 2019-12-13 07:18:33

问题


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.


回答1:


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)


来源:https://stackoverflow.com/questions/43016813/search-array-of-nested-objects-by-given-field

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!