ChatGPT解决这个技术问题 Extra ChatGPT

查找包含特定值的数组的文档

如果我有这个架构......

person = {
    name : String,
    favoriteFoods : Array
}

...其中 favoriteFoods 数组填充了字符串。我怎样才能找到所有使用猫鼬将“寿司”作为他们最喜欢的食物的人?

我希望有一些类似的东西:

PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});

(我知道mongodb中没有$contains,只是解释一下我在知道解决方案之前期望找到的东西)


y
yaya

由于 favouriteFoods 是一个简单的字符串数组,您可以直接查询该字段:

PersonModel.find({ favouriteFoods: "sushi" }, ...); // favouriteFoods contains "sushi"

但我也建议在你的模式中明确地显示字符串数组:

person = {
    name : String,
    favouriteFoods : [String]
}

相关文档可在此处找到:https://docs.mongodb.com/manual/tutorial/query-arrays/


如果 favouriteFoods 为:favouriteFoods:[{type:Schema.Types.ObjectId, ref:'Food'}],这也适用
作为来自 MySQL 等 RDBMS 的 Mongo 新手,发现这样的解决方案无需 JOIN 和额外的表就能如此简单地工作,这让我想知道为什么我没有早点开始使用 Mongo。但这并不是说任何一个 DBMS 都优于另一个 - 这取决于您的用例。
不要误会。即使是dict列表,你仍然可以这样查询。示例:PersonModel.find({ favouriteFoods.text: "sushi" }, ...); person = { name : String, favouriteFoods : [{text:String}] }
当我想找到一个至少包含两个字符串的数组时会发生什么?
@AeroWang 使用此 db.person.find( { favouriteFoods: { $all: ["sushi", "sashimi"] } } ) 将返回所有喜欢“寿司”和“生鱼片”的人,有人在下面指出了一些答案
A
Alistair Nelson

mongodb 中没有 $contains 运算符。

您可以使用 JohnnyHK 的答案。与包含 mongo 最接近的类比是 $in,使用它您的查询将如下所示:

PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);

这个对吗?使用 $in 时,mongodb 不期望值数组吗?像 { name : { $in : [ "Paul", "Dave", "Larry" , "Adam"] }}?
嗯?这是不必要的。当您有多个查询值并且文档需要匹配其中一个时,使用 $in。相反(这就是这个问题的目的),JohnnyHK 的回答是正确的。我本来打算投反对票,但我想这个答案可能对最终出现在此页面上的其他人有所帮助。
但这帮助我实际查询了几个值:D 非常感谢!
谢谢。这就是我真正想要的,搜索多个值的方法:PersonModel.find({favouriteFoods: {"$in": ["sushi", "hotdog"]}})
@MalcolmOcean 是正确的,因为 $in 运算符是相反的,具有一个数组作为值。作为数组的字段是问题所要问的。但是,如果字段和值都是数组,那么这个答案和 JohnnyHK 都是相关的,这意味着你确实需要 $in。
P
Pobe

我觉得 $all 在这种情况下会更合适。如果您正在寻找喜欢寿司的人,您可以:

PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})

正如您可能想要过滤更多您的搜索,像这样:

PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})

$in 类似于 OR,$all 类似于 AND。检查这个:https://docs.mongodb.com/manual/reference/operator/query/all/


抱歉,这是对我的问题的错误答案。我不是在寻找精确匹配,而只是寻找至少包含指定值的数组。
这是对您问题的完全有效的答案!对于一个值,使用 $all 或 $in 没有区别。如果您有几个值,例如“sushi”、“bananas”,$all 正在寻找在他们最喜爱的Food 数组中有“sushi”和“bananas”的人,如果使用 $in,您会得到有“sushi”或“bananas”的人“在他们最喜欢的食物阵列中。
是的,没有 $contains 但 $all 有点像
K
Kfir Erez

如果数组包含对象,例如 favouriteFoods 是以下对象的数组:

{
  name: 'Sushi',
  type: 'Japanese'
}

您可以使用以下查询:

PersonModel.find({"favouriteFoods.name": "Sushi"});

这很容易是最好的答案。当您赶时间时使用起来更容易。
这应该是选定的答案。如果您正在处理查询 MongoDB 中的嵌套文档数组,这就是您的操作方式。不确定它是否是最有效的,但如果这就是你想要做的,这就是你所需要的。
C
Community

如果您需要在子文档数组中查找包含 NULL 元素的文档,我发现这个查询效果很好:

db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})

此查询取自这篇文章:MongoDb query array with null values

这是一个很棒的发现,它比我自己的初始版本和错误版本好得多(结果证明它只适用于具有一个元素的数组):

.find({
    'MyArrayOfSubDocuments': { $not: { $size: 0 } },
    'MyArrayOfSubDocuments._id': { $exists: false }
})

g
gautam

lookup_food_array 的情况是数组。

match_stage["favoriteFoods"] = {'$elemMatch': {'$in': lookup_food_array}}

lookup_food_array 的情况是字符串。

match_stage["favoriteFoods"] = {'$elemMatch': lookup_food_string}

A
Amitesh Bharti

虽然同意 find() 在您的用例中最有效。仍然有 $match 聚合框架,以简化对大量条目的查询并生成对您有价值的少量结果,特别是对于分组和创建新文件。

PersonModel.aggregate([ { "$match": { $and : [{ 'favouriteFoods' : { $exists: true, $in: [ 'sushi']}}, ........ ] } }, { $project : {"_id": 0, "name" : 1} } ]);


您遇到什么错误,请详细说明?
R
Rustamjon Kirgizbaev

有一些方法可以实现这一点。第一个是 $elemMatch 运算符:

const docs = await Documents.find({category: { $elemMatch: {$eq: 'yourCategory'} }});
// you may need to convert 'yourCategory' to ObjectId

第二个是由 $in$all 运算符:

const docs = await Documents.find({category: { $in: [yourCategory] }});

或者

const docs = await Documents.find({category: { $all: [yourCategory] }});
// you can give more categories with these two approaches 
//and again you may need to convert yourCategory to ObjectId

$in 类似于 OR,$all 类似于 AND。有关详细信息,请查看此链接:https://docs.mongodb.com/manual/reference/operator/query/all/

第三个是 aggregate() 函数:

const docs = await Documents.aggregate([
    { $unwind: '$category' },
    { $match: { 'category': mongoose.Types.ObjectId(yourCategory) } }
]};

使用 aggregate() 您只能在类别数组中获得一个类别 ID。

我从我的项目中获得了这些代码片段,我必须在其中找到具有特定类别/类别的文档,因此您可以根据需要轻松自定义它。


M
Mark Ryan Orosa

对于 Loopback3,给出的所有示例都对我不起作用,或者无论如何都与使用 REST API 一样快。但它帮助我找出了我需要的确切答案。

{"where":{"arrayAttribute":{ "all" :[String]}}}


你是救生员,谢谢!那是在哪里记录的,我错过了?请问可以发链接吗?谢谢。
H
Hiran D.A Walawage

使用 populate & $in 此代码将很有用。

ServiceCategory.find().populate({
    path: "services",
    match: { zipCodes: {$in: "10400"}},
    populate: [
        {
            path: "offers",
        },
    ],
});

c
chavy

如果您在对象数组中进行搜索,您可以使用 $elemMatch。例如:

PersonModel.find({ favoriteFoods : { $elemMatch: { name: "sushi" }});

A
Alingenomen

如果您想通过 javascript 使用诸如“包含”运算符之类的东西,您可以随时使用正则表达式...

例如。假设您要检索名称为“Bartolomew”的客户

async function getBartolomew() {
    const custStartWith_Bart = await Customers.find({name: /^Bart/ }); // Starts with Bart
    const custEndWith_lomew = await Customers.find({name: /lomew$/ }); // Ends with lomew
    const custContains_rtol = await Customers.find({name: /.*rtol.*/ }); // Contains rtol

    console.log(custStartWith_Bart);
    console.log(custEndWith_lomew);
    console.log(custContains_rtol);
}

R
Rob Church

我知道这个话题很老了,但对于未来可能想知道同样问题的人来说,另一个非常低效的解决方案可能是:

PersonModel.find({$where : 'this.favouriteFoods.indexOf("sushi") != -1'});

这避免了 MongoDB 的所有优化,因此不要在生产代码中使用。


出于好奇,这样做有什么好处吗?
与公认的答案相比,这非常低效;它绕过了 Mongo 在幕后进行的所有优化,以便在接受时直接找到。
不过,这正是我需要的答案!谢谢“用户” :)

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅