我在MongoDB中有一个具有复杂结构和子文档的集合 . 该文档的结构如下:
doc1 = {
'_id': '12345678',
'url': "http//myurl/...",
'nlp':{
"status": "OK",
"entities": {
"0": {
"type" : "Person",
"relevance": "0.877245",
"text" : "Neelie Kroes"
},
"1": {
"type": "Company",
"relevance": "0.36242",
"text": "ICANN"
},
"2": {
"type": "Company",
"relevance": "0.265175",
"text": "IANA"
}
}
}
}
doc2 = {
'_id': '987456321',
'url': "http//myurl2/...",
'nlp':{
"status": "OK",
"entities": {
"0": {
"type": "Company",
"relevance": "0.96",
"text": "ICANN"
},
"1": {
"type" : "Person",
"relevance": "0.36242",
"text" : "Neelie Kroes"
},
"2": {
"type": "Company",
"relevance": "0.265175",
"text": "IANA"
}
}
}
}
我的任务是在子文档中搜索“类型”和“文本”,然后按“相关性”排序 . 使用$ elemMatch运算符,我可以执行查询:
db.resource.find({
'nlp.entities': {
'$elemMatch': {'text': 'Neelie Kroes', 'type': 'Person'}
}
});
完美,现在我必须通过相关性降序对“Person”类型的实体和“Neelie Kroes”值进行排序 .
我尝试使用普通的"sort",但是,作为manual said关于$ elemMatch中的sort(),结果可能无法反映排序顺序,因为sort()在$ elemMatch投影之前应用于数组的元素 .
事实上,_id:987456321将是第一个(相关性为0.96,但引用了ICANN) .
如何通过匹配的子文档的相关性对文档进行排序?
P.S . :我无法改变文件结构 .
1 回答
如上所述,我希望您的文档确实有一个数组,但如果$ elemMatch正在为您工作,那么他们应该 .
无论如何,您无法使用find对数组中的元素进行排序 . 但是有一种情况你可以使用.aggregate()来做到这一点:
基本上,在对包含相关匹配的文档执行$match条件之后,然后使用$project "store"
_id
字段中的原始文档和"entities" "entities"数组的"copy" .下一个$match "filters"数组内容只包含那些相关的内容 . 然后将$sort应用于"matched"文档 .
由于"original"文档存储在
_id
下,因此使用$project至"restore"文档实际必须以的结构 .这就是你对匹配的数组元素进行“排序”的方法 .
请注意 if 您在父文档的数组中有多个"matches",然后您必须使用额外的$group阶段来获取"relevance"字段的$ max值才能完成排序 .