本人在使用mongoTemplate中使用多表查询中,主表主键为id,类型为objectid,想要在purchased表对trades表进行lookup多表查询,根据good_id查询对应的trade表中的信息(Good实体类),在mongotemplate中project的convert操作坑中绕了许久,于是在此记录
主表的结构为 根据good_id进行查询,需要在project中更改其类
@Data
@Document("purchaseds")
public class Purchased {
@Id
private ObjectId id;
private String good_id;//这里为string类型 坑的起点
private int status;
private Long timestamp;
private String buyer_id;
private String owner_id;
}
从表的结构
@Data
@Document("trades")
public class Good {
@Id
private ObjectId id;
private long total_count;//总量
private long count;//余量
private List images;
private String owner_id;
private String title;
private String desc;
private Double price;
private int status;
@Transient
public static final int COMMON=1;//正常销售
@Transient
public static final int TAKE_DOWN=2;//下架了
}
所以使用lookup对good表进行查询
db.purchaseds.aggregate([
{
$lookup: {
from: "trades",
localField: "good_id",
foreignField: "_id",
as: "good_list"
}
}
])
但是因为主表的good_id字段为string类型 good表的主键为objectid类型,所以匹配不到good表中的数据
所以要通过project操作符,并在其中改变类型,所以对应的mongo应该执行为以下
db.purchaseds.aggregate([
{
$project: {
good_object_id: {//一个新的字段
$convert: {
"input": "$good_id",//主表的需要转换的字段
"to": "objectId"//转换为objectId
}
}
}
},
// 联表查询
{
$lookup: {
from: "trades",//被join的集合
localField: "good_object_id",//上个阶段指定查询的field
foreignField: "_id",//trades表下与good_object_id对应的字段
as: "good_list" //新的字段为一个list,如有需要可以查询
}
}
])
注意!!! 在进行mongotemplate的多表查询时,因为会新建一个字段(当然也可以保留)所以我们需要新建一个dto对象用于存储这个中间变量
public class purchaseDto extends Purchased {
private ObjectId good_object_id;
private List good_info;//接受返回值
}
Aggregation aggregation=Aggregation.newAggregation(
Aggregation.project()
.and(ConvertOperators.Convert.convertValue("$good_id").to("objectId"))//将good_id转换为objectId
.as("good_object_id"),//新字段名称
Aggregation.lookup("trades","good_object_id","_id","good_info")
);
AggregationResults aggregationResults= mongoTemplate.aggregate(aggregation,"purchaseds", purchaseDto.class);
System.out.println(aggregationResults);