在应用匹配过滤器之前从 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,它应该有效:)
我使用 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,它应该有效:)