例如,我有一个这样的文档:
{
name: "Test",
params: {
device: "windows",
gender: "m",
age: 28
}
}
现在我得到以下参数输入:
{
device: "windows",
gender: "m"
}
在这种情况下,我想查找与输入对象部分匹配的所有文档。有没有简单的方法可以解决此问题?我试过$ elemMatch,但这似乎只能用于数组。
答案 0 :(得分:0)
如果我正确理解了您的问题,则您有一个输入对象,其中可能包含主文档的params
对象中的一些字段,并且按任何顺序,例如:
{
device: "windows",
gender: "m"
}
{
gender: "m",
device: "windows"
}
{
device: "windows",
age: 28
}
,并且仅当输入对象中的 all 域存在于主文档中时,您才想匹配:
{
device: "linux", // NO MATCH
gender: "m"
}
{
gender: "m", // MATCH
device: "windows"
}
{
device: "windows", // NO MATCH
age: 29
}
正确吗?
您的param
对象是否始终仅包含这三个字段(device
,gender
和age
)?
如果是这样,您可以在根级别手动投影每个投影,进行匹配,然后再次“投影”:
db.my_collection.aggregate([
{
$project: {
name: 1,
params: 1,
device: "$params.device", // add these three for your match stage
gender: "$params.gender",
age: "$params.age"
}
},
{
$match: input_params
},
{
$project: {name: 1, params: 1} // back to original
}
]);
但是我假设您想对params
对象中的任意数量的字段执行此操作。
您有一种方法可以处理输入的对象?如果是这样,您可以在所有字段前面加上“ params.
”:
let input_params =
{
device: "windows",
gender: "m"
};
let new_input_params =
{
"params.device": "windows",
"params.gender": "m"
};
那么您的查询就是:
db.my_collection.find(new_input_params);
如果您无法修改输入,则可以使用$replaceRoot聚合运算符(从3.4版开始,归功于this answer)来展平{{ 1}}进入根文档。由于这将用嵌入的文档替换根文档,因此您需要首先提取感兴趣的字段,至少要提取params
字段:
_id
这将匹配文档并保留db.my_collection.aggregate([
{
$addFields: {"params.id": "$_id"} // save _id inside the params doc,
// as you will lose the original one
},
{
$replaceRoot: {newRoot: "$params"}
},
{
$match: input_params
},
...
]);
字段,您可以使用该字段再次通过_id
获取文档的其余部分:
$lookup
这将以以下格式获取您的文档:
...
{
$lookup: {
from: "my_collection",
localField: "id",
foreignField: "_id",
as: "doc"
}
},
...
要全面了解并恢复原始文档格式,您可以:
{
"device" : "windows",
"gender" : "m",
"age" : 28,
"id" : ObjectId("XXX"),
"doc" : [
{
"_id" : ObjectId("XXX"),
"name" : "Test",
"params" : {
"device" : "windows",
"gender" : "m",
"age" : 28
}
}
]
}
在撰写本文时,我不敢相信没有一种更干净的方法可以单独使用MongoDB来做到这一点,但我想不出任何办法。
我希望这会有所帮助!
答案 1 :(得分:0)
您可以使用$or运算符对 params 对象中的字段进行部分比较。您可以这样使用:
db.collection.find({
$or: [
{
"params.device": "windows"
},
{
"params.gender": "m"
}
]
})
答案 2 :(得分:0)
文档中可能有许多字段,但并非所有这些字段在需要时可能都是必要且重要的。在这种情况下,您只能使用 投影 在样本中包括必填字段。
默认情况下,MongoDB中的查询返回匹配的所有字段 文件。限制MongoDB发送到的数据量 应用程序,您可以包括一个投影文档以指定或 限制字段返回。
例如,您先前已将以下文档添加到数据库:
> db.users.insertOne({"name": "Jennifer", "gender": "female", languages: ["english", "spanish"]})
> db.users.insertOne({"name": "Alex", "gender": "male", languages: ["english", "french"]})
> db.users.insertOne({"name": "Maria", "gender": "female", languages: ["english", "german"]})
现在您要显示与字段gender
匹配且具有值female
的信息,因此您可以通过查询指定它:
db.users.find({gender: "female"}, {name: 1})
该操作返回以下文档:
{ "name" : "Jennifer", "gender" : "female" }
{ "name" : "Maria", "gender" : "female" }
<value>
可以是以下任意一项:
{ field1: <value>, field2: <value> ... }
此外,如果您不想具体化选择内容,但希望显示所有文档,那么我们可以将第一个方括号留空:
db.users.find({}, {name: 1, _id: 0})