流星。通过深度嵌套的值对我的集合进行排序

时间:2014-09-18 22:44:48

标签: mongodb meteor aggregation-framework

在我的应用程序中,我有一个代表项目组合中每个项目的图块列表。这是应用程序的主列表视图,所有项目都是从集合中提取的,没有任何排序或排序。

当我在我的路线中指定了一个可选的slug参数时(对于分配给该项目的类别),我希望能够首先在UI中显示与该类别匹配的项目,然后显示其他的&# 39; t匹配类别。

作为参考,我已经包含了以下路线的代码:

/** 
 *  Project list view (all projects) with optional 
 *  filter parameter for showing projects only by 
 *  their category name.
 */ 
this.route('list', {
    path: '/:_category_slug?',
    template: 'template_main',
    action: function() {
        if(this.ready()) {
            this.render();
        }
    },
    waitOn: function() {
        return [
            Meteor.subscribe('projects'), 
            Meteor.subscribe('formations'),
            Meteor.subscribe('categories')
        ];
    },
    data: function() {

        if(this.params._category_slug) {
            /**
             * Building up the query given the category slug and the language
             */
            var query = {};
            query['slug.' + App.language] = this.params._category_slug;

            /**
             *  Grab the category given the query, so we can get its 'id'
             */
            var category = App.models.categories.findOne(query);

            /**
             *  This is the query I need to work on so that I can achieve what I want
             */
            return App.models.projects.find({}).fetch();

        }
        else {
            return App.models.projects.find({}).fetch();
        }
    },
    yieldTemplates: {
        'components_header': {to: 'header'},
        'views_list': {to: 'content'},
        'components_footer': {to: 'footer'}
    }
});

作为参考,我还提供了与此问题相关的三个项目的数据样本。

{
    "id": 10,
    "slug": {
        "en": "sample-english-slug",
    },
    "title": {
        "en": "Sample English Title",
    },
    "description": {
        "en": "A good description.",
    },
    "category_ids": [
        {
            "id": 5
        },
        {
            "id": 6
        }
    ],
},
{
    "id": 12,
    "slug": {
        "en": "another-sample-slug",
    },
    "title": {
        "en": "Another sample title",
    },
    "description": {
        "en": "Sample description three",
    },
    "category_ids": [
        {
            "id": 1
        },
        {
            "id": 4
        }
    ],
},
{
    "id": 11,
    "slug": {
        "en": "another-sample-slug",
    },
    "title": {
        "en": "A sample title",
    },
    "description": {
        "en": "Sample description",
    },
    "category_ids": [
        {
            "id": 2
        },
        {
            "id": 5
        }
    ],
}

所以我想要做的是确保给定ID为5的类别,我希望前两个项目成为出现的前两个项目。

这可以在meteor中完成,而不必在JS中编写额外的逻辑吗?我曾经做过的一种方法是从客户端集合中更新每个项目(我不再做的事情)并设置一些额外的属性,然后在那之后进行排序。

在处理同步客户端和服务器集合时,这实际上并不可行。

1 个答案:

答案 0 :(得分:2)

来自mongodb docs

  

使用点表示法与嵌入文档中的特定字段匹配。嵌入文档中特定字段的等同匹配将选择集合中的文档,其中嵌入文档包含具有指定值的指定字段。嵌入的文档可以包含其他字段。

我不知道您是否可以使用单个查询执行此操作,但您可以concat两个使用点表示法的互补查询。

var selected = App.models.projects.find({'category_ids.id': category._id}).fetch();
var other = App.models.projects.find({'category_ids.id': {$ne: category._id}}).fetch();
return selected.concat(other);