代码之家  ›  专栏  ›  技术社区  ›  m4tt

Mongodb在集合中的特定文档字段中搜索文本

  •  0
  • m4tt  · 技术社区  · 3 年前

    我的数据库在Mongodb Atlas上,我试图在集合的所有文档的字段中搜索关键字(由用户输入)。

    结构:

    集合是“用户”

    里面的文件大约有500份

    每个文档都有一个名为“视频”的字段,看起来像:

    videos (array)
       0: (object)
         title: (string)
         views: (number)
         duration: (number)
       1: (object)
         etc.
    

    所以,如果我们说 videos[0].title 包含关键字,查询将返回整个 videos[0] 以及相关文档的其他字段。

    到目前为止,我尝试的是1:在 Users 收集现场视频并执行以下操作:

    const searchVideos = await db.collection('Users').find({
    $text: { $search: keyword }
    }).project({
    videos: 1, username: 1, image: 1, _id: 0
    }).toArray()
    

    结果: undefined

    2:我尝试通过正则表达式:

    const searchVideos = await db.collection('Users').find({
    "videos.$.title" : {$regex : keyword}
    }).project({
    videos: 1, username: 1, image: 1, _id: 0
    }).toArray()
    

    结果: 未定义

    3:我尝试使用现场视频集创建一个搜索索引(Mongo Atlas上收藏的搜索选项卡),并按照我所做的文档进行操作:

    const searchVideos = await db.collection('Users').aggregate([
            {
              $search: {
                "text": {
                  "query": keyword,
                  "path": "videos"
                }
              }
            },
            {
              $limit: 5
            },
            {
              $project: {
                "_id": 0,
                "videos": 1,
                "username": 1,
                "image": 1
              }
            }
        ])
    

    结果: 未定义

    返回undefined的console.log是:

    console.log(JSON.stringify(searchVideos[0]))
    

    我哪里做错了?

    简易操场: https://mongoplayground.net/p/ZhgxF-Dei2l

    我的收藏索引的mongodb指南针截图: enter image description here

    更新: 据我所知,下面建议的方法在某种意义上是有效的,因为它进行搜索,问题在于mongodb搜索本身,因为它基本上是这样运作的:你用 .title 包含搜索到的关键字,但返回整个文档(或该文档的所有视频,如果 .project(videos: 1) 使用。据我所知,无法指定查询来仅检索该视频对象,而不是检索所有视频(我尝试的是 .project("videos.$": 1) 之前已在其他地方成功使用,但如果与$text$search一起使用,则会抛出错误)

    更新2 :在这里找到了如何通过正则表达式实现它: Nested object text search in mongoDB

    但如果有人知道如何通过$text搜索实现同样的效果,我会分配赏金,因为我想在查询速度方面会好得多

    0 回复  |  直到 3 年前
        1
  •  2
  •   felix    3 年前

    您需要在上创建文本索引 videos.title 这样地:

    db.stores.createIndex( { "videos.title": "text" } )
    

    然后,tou可以这样查询:

    db.collection.find({
      "$text": {
        "$search": "test"
      }
    })
    

    工作游戏: mongoplayground.net/p/Ji2zSCL-T7W