给定 MongoDB 中的以下用户对象,
按 relation.$.status == 'friends'
搜索最快的方法是什么?
需要找到一种方法在 user
集合的 relation
数据中查找
,该数据包含一个值为 "friends 的对象"
(参见下面的伪查询)。
此特定集合的键已设置为 uid,因此假设下面的“用户数据”部分可能不会更改。
用户数据:
{
"_id": ObjectId('1a1a1a1a111a1a11a1a1a1a'),
"name": "Tester",
"relation": {
"2b2b2b2b2b2b2b2b2b2b2b": {
"status": 'friends',
"status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
},
"3c3c3c3c3c3c3c3c3c3c3c": {
"status": 'engaged',
"status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
}
}
}
查询:
var query = {
// pseudo, key-ignoring nested document search
'relation.$.status': 'friends'
}
var projection = {
'relation': 1
}
db.user.findOne(query, projection)
期望的输出:
{
"2b2b2b2b2b2b2b2b2b2b2b": {
"status": 'friends',
"status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
}
}
对User Data 结构的明显修正应该是使relation
成为一个对象数组,其中包含_id
和status
作为键。有点想在这里找一个临时垫片。
最佳答案
可以申请mongodb Map/Reduce这项任务的技术。
1) map
函数将从 relation
对象中确定嵌套对象,其中包含 status
字段等于 "friends"
值:
var map = function () {
for (var key in this.relation) {
var relation = this.relation[key];
if (relation.status == "friends")
emit(key, relation);
}
}
2) reduce
函数实际上什么都不做,只返回单个发出的关系:
var reduce = function (key, values) {
return values[0];
}
因此,您将拥有包含此类对象的集合:
{
_id: "2b2b2b2b2b2b2b2b2b2b2b",
value: {
status: "friends",
status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
}
}
如果您决定用数组替换relation
对象,您可以使用aggregation framework构建类似的查询。
用户数据:
{
_id: ObjectId("1a1a1a1a111a1a11a1a1a1a"),
name: "Tester",
relations: [
{
id: "2b2b2b2b2b2b2b2b2b2b2b",
status: "friends",
status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
},
{
id: "3c3c3c3c3c3c3c3c3c3c3c",
status: "engaged",
status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
}
]
}
查询:
db.collection.aggregate([
{ $unwind: "$relations" },
{ $match: { "relations.status": "friends" } },
{ $project: _id: 0,
id: "$relations.id",
status: "$relations.status",
status_changed_date: "$relations.status_chaged_date"
// etc...
}
])
输出:
{
id: "2b2b2b2b2b2b2b2b2b2b2b",
status: "friends",
status_changed_date: ISODate("2013-10-28T00:00:00.0000Z"),
// etc...
}
关于mongodb - MongoDB 中的嵌套文档值搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19666584/