gpt4 book ai didi

MongoDB查找子文档并对结果进行排序

转载 作者:行者123 更新时间:2023-12-03 15:59:06 25 4
gpt4 key购买 nike

我在 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”的实体的所有记录进行排序。

我尝试使用普通的“排序”,但是,正如 $elemMatch 中有关 sort() 的 manual said 一样,结果可能无法反射(reflect)排序顺序,因为 sort() 在 $ 之前应用于数组的元素elemMatch 投影。

事实上,_id:987456321 将是第一个(相关性为 0.96,但引用了 ICANN)。

我该如何按匹配子文档的相关性对文档进行排序?

P.S.:我无法更改文档结构。

最佳答案

如前所述,我希望您的文档实际上有一个数组,但如果 $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 字段中,并 $unwind “实体”数组的“副本”。

下一个$match将数组内容“过滤”为仅那些相关的内容。然后您应用 $sort到“匹配的”文档。

由于“原始”文档存储在 _id 下,因此您使用 $project “恢复”文档实际上必须开始的结构。

这就是对数组的匹配元素进行“排序”的方式。

请注意,如果父文档的数组中有多个“匹配项”,那么您必须使用额外的 $group阶段获取“相关性”字段的 $max 值,以便完成排序。

关于MongoDB查找子文档并对结果进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22751210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com