Mongodb检查数组的子文档中是否存在字段
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mongodb检查数组的子文档中是否存在字段相关的知识,希望对你有一定的参考价值。
我正在尝试检查数组的子文档中是否存在字段,如果存在,它将仅在回调中提供那些文档。但是每次我记录回调文档时,它都会为我提供数组中的所有值,而不是基于查询的值。
I am following this tutorial唯一的区别是我使用的是findOne函数而不是find函数,但是它仍然带给我所有值。我尝试使用查找,它做同样的事情。
我也使用与上面的链接中的示例相同的收集样式。
示例在上图中,您可以在上图中看到我的文档带有uid字段和contacts数组。我想做的是首先根据输入的uid选择一个文档。然后,在选择该文档之后,我想显示contacts数组中存在[[contacts.uid字段的值。因此,从上图可以看出,只有要显示的值为contacts [0]和contacts [3],因为contacts 1没有uid字段。
Contact.contactModel.findOne($and: [
uid: self.uid,
contacts:
$elemMatch:
uid:
$exists: true,
$ne: undefined,
]
Contact.contactModel.findOne(
uid: self.uid,
contacts:
$elemMatch:
uid:
$exists: true,
$ne: undefined,
)
var inputtedUID = "0"; // doesn't matter
db.foo.aggregate(
[
// This $match finds the docs with our input UID:
$match: "uid": inputtedUID
// ... and the $addFields/$filter will strip out those entries in contacts where contacts.uid does NOT exist. We wish we could use cond: $zz.name: $exists:true but
// we cannot use $exists here so we need the convoluted $ifNull treatment. Note we
// overwrite the original contacts with the filtered contacts:
,$addFields: contacts: $filter:
input: "$contacts",
as: "zz",
cond: $ne: [ $ifNull:["$$zz.uid",null], null]
,$limit:1 // just get 1 like findOne()
]);
show(c);
"_id" : 0,
"uid" : 0,
"contacts" : [
"uid" : "buzz",
"n" : 1
,
"uid" : "dave",
"n" : 2
]
使用RDBMS,您可以识别您的实体及其属性。接下来,您确定关系,对数据模型进行标准化,然后碰壁碰壁,以获得UPPER LEFT ABOVE AND BEYOND JOIN
™,它将回答用例A产生的问题。然后,您对用例几乎要做同样的事情B。
使用MongoDB,您可以将其颠倒过来。在查看用例时,您将尝试找出需要哪些信息来回答用例产生的问题,然后对数据进行建模,以便可以最有效的方式回答这些问题。
让我们坚持使用您的联系人数据库示例。这里要做一些假设:
- 每个用户可以有任意数量的联系人。
- 每个联系人和每个用户都需要用名称以外的其他方式唯一地标识,因为名称可以更改,而不能更改。
- 冗余不是一件坏事。
uid
字段变得多余,而变得毫无用处,因为[[is _id
字段已经唯一标识了相关数据集。用例让我们看一些用例,为便于示例,这些用例已得到简化,但会为您提供图片。
给用户,我想找到一个联系人。
- 给一个用户,我想找到他的所有联系人。
- 给一个用户,我想找到他的联系人“ John Doe”的详细信息
- 给联系人,我要编辑它。
- 给联系人,我要删除它。
"_id": new ObjectId(),
"name": new String(),
"whatever":
联系人
"_id": new ObjectId(),
"contactOf": ObjectId(),
"name": new String(),
"phone": new String()
显然,contactOf
引用必须在User集合中存在的ObjectId。实现
"_id": new ObjectId(),
"contactOf": ObjectId(),
"name": new String(),
"phone": new String()
contactOf
引用必须在User集合中存在的ObjectId。实现
给用户,我想找到一个联系人。如果有用户对象,则为_id
,并且对单个联系人的查询变得非常简单]db.contacts.findOne("contactOf":self._id)
给一个用户,我想找到他的所有联系人。
同样容易:db.contacts.find("contactOf":self._id)
给一个用户,我想找到他的联系人“ John Doe”的详细信息
db.contacts.find("contactOf":self._id,"name":"John Doe")
现在我们可以采用一种或另一种方式联系,
包括他/她/不确定/选择不说_id
,我们可以轻松地编辑/删除它:给联系人,我要编辑它。
db.contacts.update("_id":contact._id,$set:"name":"John F Doe")
[我相信,到现在为止,您已经对如何从用户的联系人中删除John有了一个了解。
注意指数
对于您的数据模型,您需要为uid
字段添加其他索引-如我们所知,这毫无用处。此外,_id
默认情况下已建立索引,因此我们可以充分利用此索引。应该在contact
集合上执行其他索引,但是:db.contact.ensureIndex("contactOf":1,"name":1)
规范化
这里完全没有做。造成这种情况的原因是多种多样的,但是最重要的是,尽管John Doe可能只有手机号码“ Mallory H Ousefriend”,但他的妻子Jane Doe也可能拥有电子邮件地址“ janes_naughty_boy@censored.com”-该地址为至少,马洛里肯定不想在约翰的联系人列表中弹出。因此,即使我们具有联系人身份,您也很可能不想反映出来。结论
_id
,并且对单个联系人的查询变得非常简单]db.contacts.findOne("contactOf":self._id)
给一个用户,我想找到他的所有联系人。
db.contacts.find("contactOf":self._id)
给一个用户,我想找到他的联系人“ John Doe”的详细信息
db.contacts.find("contactOf":self._id,"name":"John Doe")
现在我们可以采用一种或另一种方式联系,
包括他/她/不确定/选择不说_id
,我们可以轻松地编辑/删除它:给联系人,我要编辑它。
db.contacts.update("_id":contact._id,$set:"name":"John F Doe")
[我相信,到现在为止,您已经对如何从用户的联系人中删除John有了一个了解。
注意指数
对于您的数据模型,您需要为
uid
字段添加其他索引-如我们所知,这毫无用处。此外,_id
默认情况下已建立索引,因此我们可以充分利用此索引。应该在contact
集合上执行其他索引,但是:
db.contact.ensureIndex("contactOf":1,"name":1)
规范化
这里完全没有做。造成这种情况的原因是多种多样的,但是最重要的是,尽管John Doe可能只有手机号码“ Mallory H Ousefriend”,但他的妻子Jane Doe也可能拥有电子邮件地址“ janes_naughty_boy@censored.com”-该地址为至少,马洛里肯定不想在约翰的联系人列表中弹出。因此,即使我们具有联系人身份,您也很可能不想反映出来。结论
通过少量的数据重构,我们将所需的其他索引数减少到1,使查询变得更加简单,并且规避了BSON文档的大小限制。至于性能,我想我们正在谈论至少一个数量级。
以上是关于Mongodb检查数组的子文档中是否存在字段的主要内容,如果未能解决你的问题,请参考以下文章