如何使用$ indexOfCP按子文档子字符串过滤?

时间:2020-01-29 20:59:19

标签: mongodb aggregation-framework

如何从“ greetsthings”集合中返回记录,其中“ things”没有特定的子字符串?

{
    "_id" : ObjectId("5d24e6e5e8b6b11536a8519b"),
    "message" : "hello",
    "meta" : {
        "info" : "friendly score 923",
        "things" : "cat bat dragon",
    }
},
{
    "_id" : ObjectId("5d24e6e5e8b6b11536a8519c"),
    "message" : "hello",
    "meta" : {
        "info" : "confused score 622",
        "things" : "cat monkey dragon",
    }
}

我正在尝试通过{$match:{ message: { $eq: 'hello' }}}中的子字符串查询/过滤meta.things的所有“ hello message”记录

然后将 monkey 的子字符串与 meta.things 进行比较以过滤结果

当我尝试使用此 $ filter 时,它出现了"errmsg" : "input to $filter must be an array not object"

错误
db.getCollection('greetsthings').aggregate( 
[{$match:{ message: { $eq: 'hello' }}},
 {$project: {
    message: 1,
    "meta": {
       $filter: {$gte : [{$indexOfCP: ["$meta.things", "monkey"]},0]}
          }
       } 
    }
])

如何仅返回消息为 hello monkey meta.things字符串中的记录?

2 个答案:

答案 0 :(得分:1)

请尝试:

db.getCollection('greetsthings').aggregate(
    [{ $match: { message: 'hello' } },
    {
        $addFields: {
            shouldExists: { $gte: [{ $indexOfCP: ['$meta.things', "monkey"] }, 0] }, // Adds try if word monkey exists in string
            shouldNotExists: { $gte: [{ $indexOfCP: ['$meta.things', "dragon"] }, 0] } // Adds try if word dragon exists in string
        }
    }, { $match: { shouldExists: true, shouldNotExists: false } },
    { $project: { shouldExists: 0, shouldNotExists: 0 } }
    ])

测试: MongoDB-Playground

答案 1 :(得分:1)

"$meta.things"出现“语法”错误。 $expr允许对文档字段进行计算操作:

db.greetsthings.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              "$message",
              "hello"
            ]
          },
          {
            $gt: [
              {
                $indexOfCP: [
                  "$meta.things",
                  "monkey"
                ]
              },
              -1
            ]
          }
        ]
      }
    }
  }
])

MongoPlayground

还有一个否定的含义,我该如何返回消息打招呼但在meta.things字符串中没有Dragon的记录?

在字符串中搜索子字符串的出现,并返回第一次出现的UTF-8代码点索引(从零开始)。如果未找到子字符串,则返回 -1

https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfCP/

$eq: [
  {
    $indexOfCP: [
      "$meta.things",
      "dragon"
    ]
  },
   -1
]
相关问题