javascript MongoDB -数组中所有字符串的$substr

fnvucqvd  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(106)

我有这个聚合,旨在查找以给定查询开始的值,然后在结果中优先考虑精确匹配。tags字段是一个包含1个或多个字符串的数组。

results = await Post.aggregate([

    // Find all tags that begin with the given query
    { $match: { 'tags': new RegExp("^" + query, 'i') } },

    { $addFields: {
        // Add a field 'true' where one of the string values is an exact match of the query
        'exactMatch': { $eq: [ '$tags', query ] },

        // Add a field 'true' where the first 3 characters of one of the string values match the query
        'startsWith': { $eq: [ { $substr: [ '$tags', 0, 3 ] }, query ] },
    } },

    // Prioritize exact matches first
    { $sort: { 'exactMatch': -1, 'startsWith': -1 } },

    // Remove the added fields from results
    { $project: { 'exactMatch': 0, 'startsWith': 0 } }
])

tags字段是一个字符串时,这非常有效,但是我现在试图用一个字符串数组来做这件事。
问题就出在这行代码中:

// Add a field 'true' where the first 3 characters of one of the string values match the query
'startsWith': { $eq: [ { $substr: [ '$tags', 0, 3 ] }, query ] },

由于tags字段是一个数组,因此$substr函数无效并产生以下错误:
服务器错误:汇总期间PlanExecutor错误::原因:无法将BSON类型数组转换为字符串
如何将这行代码转换为针对数组中的所有值,而不是数组本身?

(编辑)样本数据、输入和预期结果

具有以下数据:

[
    {
        title: 'Post1',
        content: 'This is test post 1.',
        tags: [
            'post', '12345'
        ]
    },
    {
        title: 'Post2',
        content: 'This is test post 2.',
        tags: [
            'post', '789'
        ]
    },
    {
        title: 'Post3',
        content: 'This is test post 3.',
        tags: [
            'post', '123'
        ]
    }
]

和输入查询“123”,我希望看到以下结果:

[
    {
        title: 'Post3',
        content: 'This is test post 3.',
        tags: [
            'post', '123'
        ]
    },
    {
        title: 'Post1',
        content: 'This is test post 1.',
        tags: [
            'post', '12345'
        ]
    }
]
zkure5ic

zkure5ic1#

修改了您的查询。
由于tags是一个数组。你应该使用$filter来过滤数组中的每个元素。并匹配结果是否不是空数组。

results = await Post.aggregate([

    // Find all tags that begin with the given query
    { $match: { 'tags': new RegExp("^" + query, 'i') } },

    {
    $addFields: {
      // Add a field 'true' where one of the string values is an exact match of the query
      "exactMatch": {
        $ne: [
          {
            $filter: {
              input: "$tags",
              cond: {
                $eq: [
                  "$$this",
                  query
                ]
              }
            }
          },
          []
        ]
      },
      // Add a field 'true' where the first 3 characters of one of the string values match the query
      "startsWith": {
        $ne: [
          {
            $filter: {
              input: "$tags",
              cond: {
                $eq: [
                  {
                    $substr: [
                      "$$this",
                      0,
                      3
                    ]
                  },
                  query
                ]
              }
            }
          },
          []
        ]
      }
    }
  },

    // Prioritize exact matches first
    { $sort: { 'exactMatch': -1, 'startsWith': -1 } },

    // Remove the added fields from results
    { $project: { 'exactMatch': 0, 'startsWith': 0 } }
])

Demo @ Mongo Playground

相关问题