MongoDB Atlas搜索嵌入的文档并仅投影匹配的数组元素

mongodb atlas search embedded document and project only the matched array elements

提问人:pkpk 提问时间:11/10/2023 最后编辑:pkpk 更新时间:11/10/2023 访问量:36

问:

我有一个 mongo db 集合,结构如下。

{
_id,
name,
companies: [{
name,
rating
address
}]

}

我已经创建了一个嵌入在字段 companies.name 上的类型的 atlas 索引,当我使用此索引进行查询时,我会在结果中获取整个文档,包括数组中所有不匹配的元素。我怎样才能预测甚至找出哪个数组元素是匹配的。我不能使用突出显示,因为它不支持嵌入的文档数据类型。我可以从聚合管道中$unwind结果,但随后我必须自己在名称字段上进行匹配。对我来说,另一个选择是重组文件,但这还有其他含义。我在这里有什么选择?,我所需要的只是找出哪个元素是匹配的。

这是我的查询。

let query1 = {
      '$search': {
          'index': 'businessname',
          'embeddedDocument': {
            'path': 'companies', 
            'operator': {
              'queryString': {
                'defaultPath': 'companies.name', 
                'query': `${tags} ~ 2`
              }
            }
          }
        }
      }
 let project = {
      '$project': {
        '_id': 1,
        'displayName': 1,
        'email': 1,
        'companies.$': 1
      }

    }  

我在使用公司时收到以下错误.$: 1 MongoServerError:无效$project :: 由 :: 无法在聚合投影中使用位置投影

mongoDB 聚合框架 mongodb-atlas-search

评论

0赞 Joe 11/10/2023
您是否尝试过使用$elemMatch投影运算符?
0赞 pkpk 11/10/2023
对于$elemMatch,我是否必须指定一个条件?而且我没有条件,我也尝试了$位置投影运算符(更新了上面的代码),但是我收到错误:MongoServerError:无效$project::由::导致::无法在聚合投影中使用位置投影
0赞 Joe 11/10/2023
是的,要找出匹配的元素,请在 elemMatch 中使用相同的匹配条件
0赞 pkpk 11/10/2023
所以你建议在elemMatch中使用Atlas文本搜索?
0赞 Joe 11/11/2023
如果这可行,当然。我以为将显示的查询转换为 elemMatch 的正则表达式是微不足道的,因为无论如何都不可能使用索引作为投影阶段。

答:

0赞 Buzz Moschetti 11/10/2023 #1

对数组中的数据执行 a 操作始终返回整个数组。若要仅返回匹配的元素,请将另一个阶段添加到:$match$filter

db.foo.aggregate([
    {$match: {"companies.name":"X5"}},
    {$project: {
        company: {$filter: {input: '$companies', cond: {$eq:['$$this.name','X5']}}}
    }}  
]);

如果您知道查询应该只生成 1 个项目(例如,在本例中,在数组中是唯一的),那么您可以通过返回单个对象而不是 1 的数组来使其稍微容易一些:companies.name

    {$project: {
        X: {$arrayElemAt:[{$filter: {input: '$companies', cond: {$eq:['$$this.name','X5']}}\
},0]}
    }}

评论

0赞 pkpk 11/10/2023
我正在使用带有模糊运算符的 Atlas 搜索查询,如何在过滤器中使用它?
0赞 Buzz Moschetti 11/10/2023
作为主要阶段的工作吗?即使没有,您也始终可以在 之后的阶段中输出。regex$match$filter$search
0赞 pkpk 11/10/2023
第一阶段必须是Atlas搜索。我正在考虑在我的应用程序中进行模糊搜索以过滤返回的数组。