Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays MongoDB数组查询性能_Arrays_Mongodb_Performance_Mongodb Query - Fatal编程技术网

Arrays MongoDB数组查询性能

Arrays MongoDB数组查询性能,arrays,mongodb,performance,mongodb-query,Arrays,Mongodb,Performance,Mongodb Query,我正试图找出一个约会网站的最佳模式,比如app。用户有一个列表(可能很多),他们可以查看其他用户列表来“喜欢”和“不喜欢” 目前,我只是将列出id的其他人存储在likedBy和dislikedBy数组中。当用户“喜欢”某个列表时,它会将其列表id放入“喜欢”的列表数组中。但是,我现在想跟踪用户喜欢列表的时间戳。这将用于用户的“历史记录列表”或数据分析 我需要进行两个单独的查询: 查找此用户以前不喜欢或不喜欢的所有活动列表 以及用户“喜欢的”/“不喜欢的”选择的历史记录 按时间顺序查找用户X喜欢的

我正试图找出一个约会网站的最佳模式,比如app。用户有一个列表(可能很多),他们可以查看其他用户列表来“喜欢”和“不喜欢”

目前,我只是将列出id的其他人存储在
likedBy
dislikedBy
数组中。当用户“喜欢”某个列表时,它会将其列表id放入“喜欢”的列表数组中。但是,我现在想跟踪用户喜欢列表的时间戳。这将用于用户的“历史记录列表”或数据分析

我需要进行两个单独的查询:

查找此用户以前不喜欢或不喜欢的所有活动列表

以及用户“喜欢的”/“不喜欢的”选择的历史记录

按时间顺序查找用户X喜欢的所有列表

我当前的模式是:

listings
  _id: 'sdf3f'
  likedBy: ['12ac', 'as3vd', 'sadf3']
  dislikedBy: ['asdf', 'sdsdf', 'asdfas']
  active: bool
我可以这样做吗

listings
  _id: 'sdf3f'
  likedBy: [{'12ac', date: Date}, {'ds3d', date: Date}]
  dislikedBy: [{'s12ac', date: Date}, {'6fs3d', date: Date}]
  active: bool
我也在考虑为
选择制作一个新的集合

choices
  Id
  userId          // id of current user making the choice
  userlistId      // listing of the user making the choice
  listingChoseId  // the listing they chose yes/no
  type
  date
我不确定在执行
查找此用户以前不喜欢或不喜欢的所有活动列表时,在另一个集合中使用这些选项对性能的影响


如有任何见解,将不胜感激

显然,您认为将这些信息嵌入“清单”文档是一个好主意,这样您在这里介绍的案例中的其他使用模式就可以正常工作了。考虑到这一点,没有理由把它扔掉

但要澄清的是,您似乎想要的结构如下:

{
“_id”:“sdf3f”,
“喜欢的人”:[
{“userId”:“12ac”,“date”:ISODate(“2014-04-09T07:30:47.091Z”),
{“userId”:“as3vd”,“date”:ISODate(“2014-04-09T07:30:47.091Z”),
{“userId”:“sadf3”,“date”:ISODate(“2014-04-09T07:30:47.091Z”)}
],
“不喜欢的人”:[
{“userId”:“asdf”,“date”:ISODate(“2014-04-09T07:30:47.091Z”),
{“userId”:“sdf”,“date”:ISODate(“2014-04-09T07:30:47.091Z”),
{“userId”:“asdfas”,“date”:ISODate(“2014-04-09T07:30:47.091Z”)}
],
“活动”:真
}
这一切都很好,除了有一个陷阱。由于此内容位于两个数组字段中,因此无法在这两个字段上创建索引。这是一个限制,在复合索引中只能包含一种数组类型的字段(或多键)

因此,为了解决第一个查询无法使用索引的明显问题,您可以改为使用以下结构:

{
“_id”:“sdf3f”,
“投票”:[
{ 
“userId”:“12ac”,
“类型”:“喜欢”,
“日期”:ISODate(“2014-04-09T07:30:47.091Z”)
},
{
“用户ID”:“as3vd”,
“类型”:“喜欢”,
“日期”:ISODate(“2014-04-09T07:30:47.091Z”)
},
{ 
“用户ID”:“sadf3”,
“类型”:“喜欢”,
“日期”:ISODate(“2014-04-09T07:30:47.091Z”)
},
{ 
“用户ID”:“asdf”,
“类型”:“不喜欢”,
“日期”:ISODate(“2014-04-09T07:30:47.091Z”)
},
{
“用户ID”:“SDF”,
“类型”:“不喜欢”,
“日期”:ISODate(“2014-04-09T07:30:47.091Z”)
},
{ 
“userId”:“asdfas”,
“类型”:“不喜欢”,
“日期”:ISODate(“2014-04-09T07:30:47.091Z”)
}
],
“活动”:真
}
这允许包含此表单的索引:

db.post.ensureIndex({
“主动”:1,
“投票.用户ID”:1,
“投票日期”:1,
“投票类型”:1
})
实际上,您可能需要一些索引来适应您的使用模式,但关键是现在可以使用索引了

关于第一个案例,您有以下形式的查询:

db.post.find({“active”:true,“voates.userId”:{“$ne”:“12ac”})
考虑到您显然不会为每个用户同时提供“喜欢”和“不喜欢”选项,这是有道理的。根据该索引的顺序,至少可以使用active进行过滤,因为否定条件需要扫描其他所有内容。任何结构都无法解决这个问题

对于另一种情况,您可能希望userId位于日期之前的索引中,并作为第一个元素。那么您的查询就很简单了:

db.post.find({“vows.userId”:“12ac”})
.sort({“voces.userId”:1,“voces.date”:1})
但是您可能会想,您突然失去了一些东西,因为获得“喜欢”和“不喜欢”的计数与之前测试数组大小一样简单,但现在有点不同了。不是无法使用聚合解决的问题:

db.post.aggregate([
{“$unwind”:“$VOUTES”},
{“$组”:{
“_id”:{
“\u id”:“$\u id”,
“活动”:“$active”
},
“喜欢”:{“$sum”:{“$cond”:[
{“$eq”:[“$voates.type”,“like”]},
1.
0
]}},
“不喜欢”:{“$sum”:{“$cond”:[
{“$eq”:[“$voates.type”,“dislike”]},
1.
0
]}}
])
因此,无论您的实际使用形式如何,您都可以将文档的任何重要部分存储在分组
\u id
中,然后以简单的方式计算“喜欢”和“不喜欢”的数量

您可能也不知道,将条目从喜欢更改为不喜欢也可以在单个原子更新中完成


您可以做的还有很多,但出于给出的原因,我更喜欢这种结构。

当您没有实际说明打算如何使用它时,任何人都很难评论使用哪种模式。您可能有需要添加时间戳信息的原因,因此如果您共享了时间戳信息,您希望在您的应用程序中使用它问题,然后有一些问题需要回答。谢谢@NeilLunn,我重新编写了一点以使其更容易理解。基本上我需要能够运行查询