Mongodb:Right 如何从两个集合中收集数据?
Mongodb:Right way to collect data from two collections?
我有两个合集:一个是items
,第二个是user_item_history
。我想获取具有状态的项目。每个项目的状态存储在 user_item_history
中,项目的其他详细信息在 items
集合中。我们必须为特定用户和项目类别过滤数据。所以 user_id 和类别在 user_item_history 集合中。
user_item_history
:
{
"_id" : NumberLong(25424),
"_class" : "com.samepinch.domain.registration.UserItemHistory",
"user_id" : NumberLong(25416),
"item_id" : NumberLong(26220),
"catagoryPreference" : "BOTH",
"preference" : 0.6546536707079772,
"catagory" : "FOOD",
"status" : 1,
"createdDate" : ISODate("2015-09-02T07:50:36.760Z"),
"updatedDate" : ISODate("2015-09-02T07:55:24.105Z")
}
items
:
{
"_id" : NumberLong(26220),
"_class" : "com.samepinch.domain.item.Item",
"itemName" : "Shoes",
"categoryName" : "SHOPPING",
"attributes" : [
"WESTERN",
"CASUAL",
"ELEGANT",
"LATEST"
],
"isAccessed" : false,
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"catagoryPreference" : "FEMALE",
"startDate" : ISODate("2015-11-26T18:30:00Z"),
"endDate" : ISODate("2015-11-27T18:30:00Z"),
"location" : {
"coordinates" : [
77.24149558372778,
28.56973445677584
],
"type" : "Point",
"radius" : 2000
},
"createdDate" : ISODate("2015-11-16T10:49:11.858Z"),
"updatedDate" : ISODate("2015-11-16T10:49:11.858Z")
}
作为最终结果,我想要这种格式的文档:
{
item_id:26220,
status:1,
imageUrl: "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg"
}
更新到 MongoDB 3.2,您将能够使用 $lookup
聚合阶段,其工作方式类似于 SQL 连接。
一对多关系
如果每个items
个文档有很多对应的user_item_history
个文档,你可以得到一个项目状态列表作为一个数组。
查询
db.items.aggregate([
{
$lookup:
{
from: "user_item_history",
localField: "_id",
foreignField: "item_id",
as: "item_history"
}
},
{
$project:
{
item_id: 1,
status: "$item_history.status",
imageUrl: 1
}
}])
示例输出
{
"_id" : NumberLong(26220),
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"status" : [ 1 ]
},
{
"_id" : NumberLong(26233),
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"status" : [ 1, 2 ]
}
一对一关系
如果每个项目只有一个对应的历史文档,您可以使用以下方法来获取您请求的确切格式:
查询
db.items.aggregate([
{
$lookup:
{
from: "user_item_history",
localField: "_id",
foreignField: "item_id",
as: "item_history"
}
},
{
$unwind: "$item_history"
},
{
$project:
{
item_id: 1,
status: "$item_history.status",
imageUrl: 1
}
}])
示例输出
{
"_id" : NumberLong(26220),
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"status" : 1
}
请记住,每添加一个聚合管道阶段,性能就会下降。因此,即使您有一对一关系,您也可能更喜欢一对多查询。
应用过滤
在您的编辑中,您添加了以下内容:
we have to filter data for particular user and category of item. so user_id and category is in user_item_history collection
要过滤结果,您应该在查询中添加 $match
步骤:
db.items.aggregate([
{
$lookup:
{
from: "user_item_history",
localField: "_id",
foreignField: "item_id",
as: "item_history"
}
},
{
$unwind: "$item_history"
},
{
$match:
{
"item_history.user_id": NumberLong(25416),
"item_history.catagory": "FOOD"
}
},
{
$project:
{
item_id: 1,
status: "$item_history.status",
imageUrl: 1
}
}])
请注意 "category" 在您的示例数据中被拼错为 "catagory",因此我也不得不在上面的查询中拼错它。
我有两个合集:一个是items
,第二个是user_item_history
。我想获取具有状态的项目。每个项目的状态存储在 user_item_history
中,项目的其他详细信息在 items
集合中。我们必须为特定用户和项目类别过滤数据。所以 user_id 和类别在 user_item_history 集合中。
user_item_history
:
{
"_id" : NumberLong(25424),
"_class" : "com.samepinch.domain.registration.UserItemHistory",
"user_id" : NumberLong(25416),
"item_id" : NumberLong(26220),
"catagoryPreference" : "BOTH",
"preference" : 0.6546536707079772,
"catagory" : "FOOD",
"status" : 1,
"createdDate" : ISODate("2015-09-02T07:50:36.760Z"),
"updatedDate" : ISODate("2015-09-02T07:55:24.105Z")
}
items
:
{
"_id" : NumberLong(26220),
"_class" : "com.samepinch.domain.item.Item",
"itemName" : "Shoes",
"categoryName" : "SHOPPING",
"attributes" : [
"WESTERN",
"CASUAL",
"ELEGANT",
"LATEST"
],
"isAccessed" : false,
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"catagoryPreference" : "FEMALE",
"startDate" : ISODate("2015-11-26T18:30:00Z"),
"endDate" : ISODate("2015-11-27T18:30:00Z"),
"location" : {
"coordinates" : [
77.24149558372778,
28.56973445677584
],
"type" : "Point",
"radius" : 2000
},
"createdDate" : ISODate("2015-11-16T10:49:11.858Z"),
"updatedDate" : ISODate("2015-11-16T10:49:11.858Z")
}
作为最终结果,我想要这种格式的文档:
{
item_id:26220,
status:1,
imageUrl: "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg"
}
更新到 MongoDB 3.2,您将能够使用 $lookup
聚合阶段,其工作方式类似于 SQL 连接。
一对多关系
如果每个items
个文档有很多对应的user_item_history
个文档,你可以得到一个项目状态列表作为一个数组。
查询
db.items.aggregate([
{
$lookup:
{
from: "user_item_history",
localField: "_id",
foreignField: "item_id",
as: "item_history"
}
},
{
$project:
{
item_id: 1,
status: "$item_history.status",
imageUrl: 1
}
}])
示例输出
{
"_id" : NumberLong(26220),
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"status" : [ 1 ]
},
{
"_id" : NumberLong(26233),
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"status" : [ 1, 2 ]
}
一对一关系
如果每个项目只有一个对应的历史文档,您可以使用以下方法来获取您请求的确切格式:
查询
db.items.aggregate([
{
$lookup:
{
from: "user_item_history",
localField: "_id",
foreignField: "item_id",
as: "item_history"
}
},
{
$unwind: "$item_history"
},
{
$project:
{
item_id: 1,
status: "$item_history.status",
imageUrl: 1
}
}])
示例输出
{
"_id" : NumberLong(26220),
"imageUrl" : "0bd2838e-9349-432a-a200-6e6b659e853eitemcompressed.jpg",
"status" : 1
}
请记住,每添加一个聚合管道阶段,性能就会下降。因此,即使您有一对一关系,您也可能更喜欢一对多查询。
应用过滤
在您的编辑中,您添加了以下内容:
we have to filter data for particular user and category of item. so user_id and category is in user_item_history collection
要过滤结果,您应该在查询中添加 $match
步骤:
db.items.aggregate([
{
$lookup:
{
from: "user_item_history",
localField: "_id",
foreignField: "item_id",
as: "item_history"
}
},
{
$unwind: "$item_history"
},
{
$match:
{
"item_history.user_id": NumberLong(25416),
"item_history.catagory": "FOOD"
}
},
{
$project:
{
item_id: 1,
status: "$item_history.status",
imageUrl: 1
}
}])
请注意 "category" 在您的示例数据中被拼错为 "catagory",因此我也不得不在上面的查询中拼错它。