描述:
db.acticles.aggregate([
{
$lookup:
{
from:"acticlesMaptags",
localField:"_id",
foreignField:"acticleid",
as:"tagid"
}
}
])
acticlesMaptags集合中的acticleid字段存在与acticles集合中的_id相匹配的数据,但是查询出来的tagid却为空。
下面是acticles集合与acticlesMaptags集合:
{
"RECORDS": [
{
"_id": "6436ba99e0180000d2007562",
"title": "这是标题",
"text": "这是内容",
"descripe": "接上期,MongoDB 的事务操作已经操作了,但细节和参数并没有弄清楚,通过mongodb 的事务操作主要分为以下几个部分1 Session.startTransaction2 ...",
"time": "1681308703868"
},
{
"_id": "6436ba9de0180000d2007563",
"title": "这是标题",
"text": "这是内容",
"descripe": "事务是数据库中处理的逻辑单元,包括一个或多个数据库操作,既可以是读操作,也可以是写...要使用事务,你所部署的 MongoDB 必须是 MongoDB 4.2 或更高版本,MongoDB 的驱动程序必须更新为 MongoDB 4.2 或更高版本。...",
"time": "1681308703868"
},
{
"_id": "6436c0dce0180000d200756c",
"title": "测试标题",
"text": "这是内容",
"descripe": "的哦奥球",
"time": "1681308703868"
}
]
}
{
"RECORDS": [
{
"_id": "6436bfb9e0180000d200756a",
"acticleid": "6436ba99e0180000d2007562",
"tagid": "6436be71e0180000d2007565"
},
{
"_id": "6436bff2e0180000d200756b",
"acticleid": "6436ba9de0180000d2007563",
"tagid": "6436bebae0180000d2007569"
},
{
"_id": "6436c316e0180000d200756d",
"acticleid": "6436c0dce0180000d200756c",
"tagid": "6436be97e0180000d2007567"
},
{
"_id": "6436c38ce0180000d200756e",
"acticleid": "6436c0dce0180000d200756c",
"tagid": "6436be97e0180000d2007567"
},
{
"_id": "6438b4b0fe580000ec007ff2",
"acticleid": "6436ba9de0180000d2007563",
"tagid": "6436be97e0180000d2007567"
}
]
}
ai的回答:
根据您提供的文档,从逻辑上看 $lookup 查询语句是正确的,但是结果为空可能有以下几个可能性:
acticlesMaptags 集合中的 acticleid 字段中的值与 acticles 集合中的 _id 字段值不完全匹配。请注意确保两个集合之间使用相同类型的字段进行关联(例如,都使用 ObjectID 类型)。
如果您在执行 $lookup 查询时未指定相关的查询条件,则将从 acticlesMaptags 集合中检索所有与 acticles 集合中的文档匹配的记录,这可能会返回大量数据并导致查询超时或者无法查询出结果。 基于您的数据,这种情况似乎不太可能发生。
另外一个可能性是访问权限问题。请确保您有足够的权限访问 acticlesMaptags 集合。
我们建议你通过对 acticlesMaptags 进行简单的聚合查询来验证集合中是否存在与 acticles 集合中的 _id 字段匹配的文档。例如,可以执行以下查询:
db.acticlesMaptags.aggregate([
{
$match: {
acticleid: {
$in: db.acticles.distinct("_id")
}
},
}
])
此查询将返回 acticlesMaptags 集合中与 acticles 集合中的 _id 字段匹配的文档。如果没有返回结果,则可能存在相关性或访问权限问题,您需要进一步进行排查。
解决
根据ai的回答我可以判断是类型不相同出现的问题,于是我还问了下ai的解决方案:
在MongoDB中,使用lookup可以实现表连接的操作。
lookup可以实现表连接的操作。lookup运算符可以将文档从一个集合连接到另一个集合,并将结果作为新的嵌入式文档数组返回。
如果要连接两个不同类型的字段(例如ObjectId和字符串),可以使用以下方式:
假设有两个集合:orders和customers。orders集合中包含一个名为customerId的ObjectId字段,而customers集合中包含一个名为_id的字符串字段。要在orders集合中查找所有订单,以及与之相关联的客户信息,请执行以下步骤:
db.orders.aggregate([
{
$lookup: {
from: "customers",
localField: "customerId",
foreignField: "_id",
as: "customer_info"
}
}
])
上述代码将在orders集合中查找所有订单,并将customer_info字段添加到每个订单文档中。该字段是一个由查询customers集合得到的包含客户信息的数组。其中localField指定了在orders集合中用于匹配的字段,而foreignField指定了在customers集合中用于匹配的字段。
需要注意的一点是,如果要连接的两个字段类型不同,则需要将localField字段的值写成一个对象,其中包含了类似 $toString 和 $toObjectId 等转换方法。例如,如果orders集合的customerId字段是一个字符串而非ObjectId,则可采用如下方式进行转换:
db.orders.aggregate([
{
$lookup: {
from: "customers",
localField: { $toObjectId: "$customerId" },
foreignField: "_id",
as: "customer_info"
}
}
])
上述代码将使用$toObjectId运算符将customerId字段从字符串转换为ObjectId。然后,它将在customers集合中查找与之匹配的文档,并将结果包含在customer_info字段中。
最终我的解决方案
添加一个转换为string类型的_id字段。
db.acticles.aggregate([
{
$addFields: {
acticleid: { $toString: "$_id" }
}
},
{
$lookup:
{
from:"acticlesMaptags",
localField:"acticleid",
foreignField:"acticleid",
as:"tagid"
}
}
])
成功!!!