Meteor:在集合中仅返回嵌套数组中的单个对象(Meteor: Return only single object in nested array within collection)
我试图用Meteor的
find().fetch()
过滤返回的数据集,只包含一个对象,如果我查询单个子文档但是我收到几个,有些甚至不包含任何子文档,它看起来不是很有用匹配条款。我有一个简单的混合数据集合,如下所示:
{ "_id" : ObjectId("570d20de3ae6b49a54ee01e7"), "name" : "Entertainment", "items" : [ { "_id" : ObjectId("57a38b5f2bd9ac8225caff06"), "slug" : "this-is-a-long-slug", "title" : "This is a title" }, { "_id" : ObjectId("57a38b835ac9e2efc0fa09c6"), "slug" : "mc", "title" : "Technology" } ] } { "_id" : ObjectId("570d20de3ae6b49a54ee01e8"), "name" : "Sitewide", "items" : [ { "_id" : ObjectId("57a38bc75ac9e2efc0fa09c9"), "slug" : "example", "name" : "Single Example" } ] }
我可以使用MongoDB shell轻松查询嵌套
items
数组中的特定对象,如下所示:db.categories.find( { "items.slug": "mc" }, { "items.$": 1 } );
这会返回好的数据,它只包含我想要使用的单个对象:
{ "_id" : ObjectId("570d20de3ae6b49a54ee01e7"), "items" : [ { "_id" : ObjectId("57a38b985ac9e2efc0fa09c8") "slug" : "mc", "name" : "Single Example" } ] }
但是,如果直接尝试Meteor中的类似查询:
/* server/publications.js */ Meteor.publish('categories.all', function () { return Categories.find({}, { sort: { position: 1 } }); }); /* imports/ui/page.js */ Template.page.onCreated(function () { this.subscribe('categories.all'); }); Template.page.helpers({ items: function () { var item = Categories.find( { "items.slug": "mc" }, { "items.$": 1 } ) .fetch(); console.log('item: %o', item); } });
结果并不理想,因为它返回整个匹配的块,以及嵌套
items
数组中的每个对象:{ "_id" : ObjectId("570d20de3ae6b49a54ee01e7"), "name" : "Entertainment", "boards" : [ { "_id" : ObjectId("57a38b5f2bd9ac8225caff06") "slug" : "this-is-a-long-slug", "name" : "This is a title" }, { "_id" : ObjectId("57a38b835ac9e2efc0fa09c6") "slug" : "mc", "name" : "Technology" } ] }
然后我当然可以使用for循环进一步过滤返回的游标以获得所需的对象,但是在处理更大的数据集时,这似乎是不可扩展的并且非常低效。
我无法理解为什么Meteor的
find
返回一个完全不同于MongoDB shellfind
的数据集,唯一合理的解释是两个函数签名都不同。我应该将嵌套集合分解为更小的集合并采用更多关系数据库方法(即存储对ObjectID的引用)和查询集合到集合的数据,还是有更强大的方法可用于有效地将大数据集过滤成单个如上所示,只包含匹配对象的对象?
I'm attempting to filter returned data sets with Meteor's
find().fetch()
to contain just a single object, it doesn't appear very useful if I query for a single subdocument but instead I receive several, some not even containing any of the matched terms.I have a simple mixed data collection that looks like this:
{ "_id" : ObjectId("570d20de3ae6b49a54ee01e7"), "name" : "Entertainment", "items" : [ { "_id" : ObjectId("57a38b5f2bd9ac8225caff06"), "slug" : "this-is-a-long-slug", "title" : "This is a title" }, { "_id" : ObjectId("57a38b835ac9e2efc0fa09c6"), "slug" : "mc", "title" : "Technology" } ] } { "_id" : ObjectId("570d20de3ae6b49a54ee01e8"), "name" : "Sitewide", "items" : [ { "_id" : ObjectId("57a38bc75ac9e2efc0fa09c9"), "slug" : "example", "name" : "Single Example" } ] }
I can easily query for a specific object in the nested
items
array with the MongoDB shell as this:db.categories.find( { "items.slug": "mc" }, { "items.$": 1 } );
This returns good data, it contains just the single object I want to work with:
{ "_id" : ObjectId("570d20de3ae6b49a54ee01e7"), "items" : [ { "_id" : ObjectId("57a38b985ac9e2efc0fa09c8") "slug" : "mc", "name" : "Single Example" } ] }
However, if a similar query within Meteor is directly attempted:
/* server/publications.js */ Meteor.publish('categories.all', function () { return Categories.find({}, { sort: { position: 1 } }); }); /* imports/ui/page.js */ Template.page.onCreated(function () { this.subscribe('categories.all'); }); Template.page.helpers({ items: function () { var item = Categories.find( { "items.slug": "mc" }, { "items.$": 1 } ) .fetch(); console.log('item: %o', item); } });
The outcome isn't ideal as it returns the entire matched block, as well as every object in the nested
items
array:{ "_id" : ObjectId("570d20de3ae6b49a54ee01e7"), "name" : "Entertainment", "boards" : [ { "_id" : ObjectId("57a38b5f2bd9ac8225caff06") "slug" : "this-is-a-long-slug", "name" : "This is a title" }, { "_id" : ObjectId("57a38b835ac9e2efc0fa09c6") "slug" : "mc", "name" : "Technology" } ] }
I can then of course filter the returned cursor even further with a for loop to get just the needed object, but this seems unscalable and terribly inefficient while dealing with larger data sets.
I can't grasp why Meteor's
find
returns a completely different set of data than MongoDB's shellfind
, the only reasonable explanation is both function signatures are different.Should I break up my nested collections into smaller collections and take a more relational database approach (i.e. store references to ObjectIDs) and query data from collection-to-collection, or is there a more powerful means available to efficiently filter large data sets into single objects that contain just the matched objects as demonstrated above?
原文:https://stackoverflow.com/questions/38794278
最满意答案
你可能在这里错过了正确的逻辑,因为它可以像你期望的那样工作。 这是范围的典型问题,因为它们可能远远不够直观。
例如,如果事件A跨越时间t = 2到t = 6,并且您想知道在t = 4和t = 5之间发生了什么事件,除非得到正确的范围,否则您将找不到A.
正确的查询应该是:
SELECT ... WHERE date_s <= :searchd AND date_e >= :searchs
这假设
:searchd
:searchs
到你的范围的结尾,并且:searchs
成为开始。 在长形式中,这意味着“查找事件在范围结束之前开始并在范围开始之后结束的所有事件”。 我相信这会起作用,就像在人为的例子中那样,6 >= 5
和2 <= 4
这样事件才有资格。You're probably missing the correct logic here for this to work as you expect. This is a typical problem with ranges as they can be considerably less than intuitive.
For instance, if event A spanned time t=2 through t=6 and you want to know what events were going on between t=4 and t=5, you won't find A unless you get your ranges right.
The correct query should be:
SELECT ... WHERE date_s <= :searchd AND date_e >= :searchs
This presumes
:searchd
to be the end of your range, and:searchs
to be the start. In long form this means "Find all events where the event started before the end of the range and ended after the start of the range." I believe this would work, as in the contrived example,6 >= 5
and2 <= 4
so that event would qualify.
相关问答
更多-
有什么数据库专业书籍介绍?[2022-05-19]
mysql -
我喜欢diff和rle的方法,但会这样做 with(rle(diff(olap)), { dur <- max(lengths[values==1]) end <- sum(lengths[1:which(values==1 & lengths==dur)])+1 list(duration=dur+1, start=olap[end-dur], end=olap[end]) }) # $duration # [1] 10 # # $start # [1] 1997 # # $ ...
-
您还可以使用DayOfYear获得一年中的日期编号,因此1月1日是第1天.1月1日是第213天。 这将完全无视这一年。 SELECT * FROM `table` WHERE DayOfYear(`birthday`) BETWEEN DayOfYear('01-01-01') AND DayOfYear('2200-03-15') 找到: 日期之间的日期,无视年份 You could also use DayOfYear to get the day number in a year, so 1 j ...
-
你可能在这里错过了正确的逻辑,因为它可以像你期望的那样工作。 这是范围的典型问题,因为它们可能远远不够直观。 例如,如果事件A跨越时间t = 2到t = 6,并且您想知道在t = 4和t = 5之间发生了什么事件,除非得到正确的范围,否则您将找不到A. 正确的查询应该是: SELECT ... WHERE date_s <= :searchd AND date_e >= :searchs 这假设:searchd :searchs到你的范围的结尾,并且:searchs成为开始。 在长形式中,这意味着“查找事 ...
-
select * from YourTable where [start year] <= 2006 and 2005 <= [end year] select * from YourTable where [start year] <= 2006 and 2005 <= [end year]
-
您可以使用WHERE子句来过滤数据: select name, age, job, gender from hello where age >=20 and age <=30 and gender = 'm' 使用Demo查看SQL小提琴 这也可以使用BETWEEN编写: select name, age, job, gender from hello where age between 20 and 30 and gender = 'm' 使用Demo查看SQL小提琴 。 通常情况下,您需 ...
-
MySQL的。(MySQL. Select years range)[2022-11-14]
SELECT Make, Model, CASE WHEN MIN(Year) = MAX(Year) THEN MIN(Year) ELSE CONCAT(MIN(Year), '-', MAX(Year)) END As Year, OtherColumns FROM tableName GROUP BY Make, Model, OtherColumns SELECT Make, Model, CASE WHE ... -
我认为你的意思是激活期不能重叠,对吧? 然后检查它的查询将如下所示: select distinct t1.* from threshold t1, threshold t2 where t1.id_indicator = t2.id_indicator and t1.id_threshold <> t2.id_threshold and ( t1.activation_begin_value BETWEEN t2.activation_begin_value and t2 ...
-
<%= simple_form_for(@model) do |f| %> <%= f.input :birthday, start_year: Date.today.year - 110, end_year: Date.today.year %><%= f.button :submit, "Submit" %><% end %> 这给出了从当年到110年前可能的年份选择。 在这里找 ...
-
解决问题的最简单方法是明确使用datetime对象作为索引。 熊猫为此提供了一个实用工具: years = pd.date_range('2008','2015', freq='AS') freq参数采用偏移量。 您可以创建自己的或使用其中一个内置别名 。 The easiest way to fix your problem is to explicitly use datetime objects as your index. Pandas provides a utility for this: y ...