按附加关键字对 MongoDB 查询进行排序
Sort MongoDB query by additional keyword
我正在 Flask + MongoDB 上为人力资源网站构建 REST Api。我需要按编程语言、经验、城市等筛选搜索结果
我也有一个过滤器 'framework'。但是我还需要实现一个额外的框架过滤器,它“很高兴,但不是必需的”我只需要对项目顺序进行排序,包括额外的框架。
框架本身作为字符串列在 'about' 字段中,因此我使用正则表达式来查找它。
例如,我正在寻找 Python 开发人员,他必须具备 Flask 知识,但也很高兴了解 React。所以我需要这样的搜索结果:
- 开发人员 A:Python、Flask、React
- 开发人员 B:Python、Flask、React
- Def C:Python,烧瓶
问题是第二个框架不是强制性的,而第一个框架是强制性的,所以我无法使用“$or”或“$in”进行查询。我看到的唯一选择是查询第一个框架,然后根据是否存在第二个框架对其进行排序。
有没有办法在MongoDB中实现它?
好的,经过一些研究我找到了解决方案:
def _filter_by_additional_framework(collection, query):
results = collection.aggregate([
{'$limit': 1},
{'$lookup':
{
'from': 'profiles',
'pipeline': [
{'$match': {
'$text': {
'$search': f"\"{query['framework']}\" \"{query['framework2']}\""}}
},
{'$sort': {'Rating': DESCENDING}}
], 'as': 'col1'}},
{'$lookup':
{
'from': 'profiles',
'pipeline': [
{'$match': {
'$text': {
'$search': f"\"{query['framework']}\" -\"{query['framework2']}\""}}
},
{'$sort': {'Rating': DESCENDING}}
], 'as': 'col2'}},
{'$project': {'union': {'$concatArrays': ["$col1", "$col2"]}}},
{'$unwind': '$union'},
{'$replaceRoot': {'newRoot': '$union'}},
{'$project': search_result_order()},
], collation=Collation(locale="en_US", numericOrdering=True))
return results
它通过集合中的同一字段执行 2 次查找(第一个查找 Flask AND React ('"Flask" "React"'),第二个查找 Flask AND NOT React ('"Flask" -" React"')。我还必须向某些字段添加文本索引以执行文本查找。
此外,您可能会注意到每个管道中都有一个 $sort 表达式。这是为了额外的排序(在我的例子中是评级)。聚合中的第二个参数(排序规则)用于按整数对字符串字段进行排序。因此,您可以根据需要分别对每个查询进行排序,或者您可以将排序表达式移出管道并对整个查询组合进行排序。
我正在 Flask + MongoDB 上为人力资源网站构建 REST Api。我需要按编程语言、经验、城市等筛选搜索结果
我也有一个过滤器 'framework'。但是我还需要实现一个额外的框架过滤器,它“很高兴,但不是必需的”我只需要对项目顺序进行排序,包括额外的框架。
框架本身作为字符串列在 'about' 字段中,因此我使用正则表达式来查找它。
例如,我正在寻找 Python 开发人员,他必须具备 Flask 知识,但也很高兴了解 React。所以我需要这样的搜索结果:
- 开发人员 A:Python、Flask、React
- 开发人员 B:Python、Flask、React
- Def C:Python,烧瓶
问题是第二个框架不是强制性的,而第一个框架是强制性的,所以我无法使用“$or”或“$in”进行查询。我看到的唯一选择是查询第一个框架,然后根据是否存在第二个框架对其进行排序。
有没有办法在MongoDB中实现它?
好的,经过一些研究我找到了解决方案:
def _filter_by_additional_framework(collection, query):
results = collection.aggregate([
{'$limit': 1},
{'$lookup':
{
'from': 'profiles',
'pipeline': [
{'$match': {
'$text': {
'$search': f"\"{query['framework']}\" \"{query['framework2']}\""}}
},
{'$sort': {'Rating': DESCENDING}}
], 'as': 'col1'}},
{'$lookup':
{
'from': 'profiles',
'pipeline': [
{'$match': {
'$text': {
'$search': f"\"{query['framework']}\" -\"{query['framework2']}\""}}
},
{'$sort': {'Rating': DESCENDING}}
], 'as': 'col2'}},
{'$project': {'union': {'$concatArrays': ["$col1", "$col2"]}}},
{'$unwind': '$union'},
{'$replaceRoot': {'newRoot': '$union'}},
{'$project': search_result_order()},
], collation=Collation(locale="en_US", numericOrdering=True))
return results
它通过集合中的同一字段执行 2 次查找(第一个查找 Flask AND React ('"Flask" "React"'),第二个查找 Flask AND NOT React ('"Flask" -" React"')。我还必须向某些字段添加文本索引以执行文本查找。
此外,您可能会注意到每个管道中都有一个 $sort 表达式。这是为了额外的排序(在我的例子中是评级)。聚合中的第二个参数(排序规则)用于按整数对字符串字段进行排序。因此,您可以根据需要分别对每个查询进行排序,或者您可以将排序表达式移出管道并对整个查询组合进行排序。