doulan8152 2018-01-20 11:33
浏览 69
已采纳

搜索嵌入在mongodb中的对象中的对象中的公共字段

I have a document like bellow:

books: [
{_id: 1,chapters:{0:{title:'ch1'},1:{title:'ch2'},2:{title:'ch3'}},description:'book one'},
{_id: 2,chapters:{0:{title:'ch4'},1:{title:'ch2'},2:{title:'ch5'}},description:'book two'},
{_id: 3,chapters:{0:{title:'ch6'},1:{title:'ch7'},2:{title:'ch8'}},description:'book three'},
{_id: 4,chapters:{0:{title:'ch9'},1:{title:'ch10'},2:{title:'ch11'}},description:'book four'}
]

so my question is this : how can i find object in this collection that has a chapter with title of 'ch2' ? and i can't change the data and structure of that!

perhaps this is a help: i using embedded document from jenssegers/laravel-mongodb. if there is a better library for using mongodb in laravel please let me know! thanks

  • 写回答

1条回答 默认 最新

  • dongyimeng3764 2018-01-20 12:07
    关注

    Since your collection is huge 100m, try indexing the fields, and do $text search on collection

    creating text index

    https://docs.mongodb.com/manual/core/index-text/

    $text search

    https://docs.mongodb.com/manual/reference/operator/query/text/index.html

    > db.books.ensureIndex({"$**" : "text"})
    

    index

    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 2,
        "note" : "all indexes already exist",
        "ok" : 1
    }
    

    result

    > 
    > db.books.find({$text : {$search : "ch2"}})
    { "_id" : 2, "chapters" : { "0" : { "title" : "ch4" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch5" } }, "description" : "book two" }
    { "_id" : 1, "chapters" : { "0" : { "title" : "ch1" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch3" } }, "description" : "book one" }
    > 
    

    This is possible with out text index, by to converting the chapters $objectToArray for searching and back to $arrayToObject, but this will do this for 100m documents, not suitable for your case

    db.books.aggregate(
        [
            {$project : { description : 1, arr : {$objectToArray : "$$ROOT.chapters"}}}, 
            {$match : {"arr.v.title" : "ch2"}}, 
            {$project : { description : 1 , chapters : { $arrayToObject : "$$ROOT.arr"}}}
        ]
    ).pretty()
    

    result

    > db.books.aggregate([{$project : { description : 1, arr : {$objectToArray : "$$ROOT.chapters"}}}, {$match : {"arr.v.title" : "ch2"}}, {$project : { description : 1 , chapters : { $arrayToObject : "$$ROOT.arr"}}}])
    { "_id" : 1, "description" : "book one", "chapters" : { "0" : { "title" : "ch1" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch3" } } }
    { "_id" : 2, "description" : "book two", "chapters" : { "0" : { "title" : "ch4" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch5" } } }
    > 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)