在应用匹配过滤器之前从 MongoDB Atlas Search 获取唯一值列表

Get a list of unique values from MongoDB Atlas Search before match filters are applied

我使用 MongoDB Atlas Search 来搜索我数据库中的资源列表(我使用的是 Mongoose,因此语法略有不同):

const allApprovedSearchResults = await Resource.aggregate([{
    $search: {
        compound: {
            should: [
                {
                    wildcard: {
                        query: queryStringSegmented,
                        path: ["title", "link", "creatorName"],
                        allowAnalyzedField: true,
                    }
                },
                {
                    wildcard: {
                        query: queryStringSegmented,
                        path: ["topics"],
                        allowAnalyzedField: true,
                        "score": { "boost": { "value": 2 } },
                    }
                }
                ,
                    {
                    wildcard: {
                        query: queryStringSegmented,
                        path: ["description"],
                        allowAnalyzedField: true,
                        score: { "boost": { "value": .2 } },
                    }
                }
            ]
        }
    }
}])
    .match(matchFilter)
    .exec();

const uniqueLanguagesInSearchResults = [...new Set(allApprovedSearchResults.map(resource => resource.language))];

最后一行检索结果集中的所有唯一语言。 但是,在应用 .match(matchFilter) 之前,我想要一份所有语言的列表。 有没有办法做到这一点,而不需要 运行 不使用过滤器进行第二次搜索?

您可以在 $search:

之后使用 $facet
.aggregate([
  {
    $search: {
        compound: {
            should: [
                {
                    wildcard: {
                        query: queryStringSegmented,
                        path: ["title", "link", "creatorName"],
                        allowAnalyzedField: true,
                    }
                },
                {
                    wildcard: {
                        query: queryStringSegmented,
                        path: ["topics"],
                        allowAnalyzedField: true,
                        "score": { "boost": { "value": 2 } },
                    }
                }
                ,
                    {
                    wildcard: {
                        query: queryStringSegmented,
                        path: ["description"],
                        allowAnalyzedField: true,
                        score: { "boost": { "value": .2 } },
                    }
                }
            ]
        }
    }
},
  {
    "$facet": {
      "filter": [
        {$match: matchFilter}
      ],
      "allLanguages ": [
        {$group: {_id: 0, all: {$addToSet: '$language'}}}, //<- replace '$language' with real field name
      ]
    }
  }
])

您没有提供结构,所以我假设 'language' 是字段名称。 $facet 创建一个分叉 - 一个名为 'filter' 的部分将仅包含过滤后的结果,而另一个名为 allLanguages 的部分将包含一组所有语言,而不管 filter.You 可以在每个 $facet 管道中添加 $project 个步骤来格式化数据。

根据 docs,它应该有效:)