我在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"
}
}
}
}
我的任务是在子文档中搜索“type”和“text”,然后按“related”排序。 使用$ elemMatch运算符,我可以执行查询:
db.resource.find({
'nlp.entities': {
'$elemMatch': {'text': 'Neelie Kroes', 'type': 'Person'}
}
});
完美,现在我必须按照“人物”类型的实体对所有记录进行排序,并按相关性降序对“Neelie Kroes”进行排序。
我尝试使用正常的“排序”,但是,作为$ {emmM}中关于sort()的manual said,结果可能无法反映排序顺序,因为sort()已应用于元素$ elemMatch投影前的数组。
事实上,_id:987456321将是第一个(相关性为0.96,但引用了ICANN)。
如何根据匹配的子文档的相关性对文档进行排序?
P.S。:我无法更改文档结构。
答案 0 :(得分:1)
如上所述,我希望您的文档确实有一个数组,但是如果$ elemMatch正在为您工作,那么他们应该。
无论如何,您无法使用find对数组中的元素进行排序。但有一种情况是您可以使用.aggregate()
执行此操作:
db.collection.aggregate([
// Match the documents that you want, containing the array
{ "$match": {
"nlp.entities": {
"$elemMatch": {
"text": "Neelie Kroes",
"type": "Person"
}
}
}},
// Project to "store" the whole document for later, duplicating the array
{ "$project": {
"_id": {
"_id": "$_id",
"url": "$url",
"nlp": "$nlp"
},
"entities": "$nlp.entities"
}},
// Unwind the array to de-normalize
{ "$unwind": "$entities" },
// Match "only" the relevant entities
{ "$match": {
"entities.text": "Neelie Kroes",
"entities.type": "Person"
}},
// Sort on the relevance
{ "$sort": { "entities.relevance": -1 } },
// Restore the original document form
{ "$project": {
"_id": "$_id._id",
"url": "$_id.url",
"nlp": "$_id.nlp"
}}
])
基本上,在对包含相关匹配的文档执行$match
条件后,您可以使用$project
“存储”_id
字段中的原始文档和{{3} “实体”数组的“副本”。
下一个$unwind
“过滤”数组内容,只过滤那些相关的内容。然后将$match
应用于“匹配”文档。
由于“原始”文档存储在_id
下,您可以使用$sort
来“恢复”文档实际上必须开始的结构。
这就是你对匹配的数组元素进行“排序”的方法。
请注意,如果您在父文档的数组中有多个“匹配”,那么您必须使用额外的$project
阶段来获取“$ max”值相关性“字段以完成您的排序。