dounianluo0086 2017-03-25 13:16
浏览 75
已采纳

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

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条回答 默认 最新

  • duange051858 2017-03-25 15:15
    关注

    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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于下拉菜单选项关联的问题
  • ¥15 如何修改pca中的feature函数
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R