【问题标题】:dynamic mongodb query based on user preference in MeteorMeteor中基于用户偏好的动态mongodb查询
【发布时间】:2023-03-15 14:25:01
【问题描述】:

根据登录用户的偏好,我想创建一个集合并在视图中显示。

我对 mongodb 没有任何经验,现在我以这个巨大的 if/else 语句结束,而且它已经很慢了(DB 中有 7 个用户)。但是 afaik 它确实给了我正确的结果。

Meteor.publish('listprofiles', function () {

    if ( ! this.userId ) return [];  

    var user =  Meteor.users.findOne({ _id: this.userId }, {
                    fields : {
                        'profile.gender': 1,
                        'profile.preference': 1
                    }
                }),
        query;

    user.gender = user.profile.gender;
    user.preference = user.profile.preference;

    if (user.gender === 'man') {
        if (user.preference === 'straight') {
            query = {
                        $and: [
                            { 'profile.gender': 'woman' },
                            { 
                                $or : [{ 'profile.preference' : 'straight' }, 
                                       { 'profile.preference' : 'bi' }] 
                            }
                        ]
                    };

        } else if (user.preference === 'gay') {
            query = {
                        $and: [
                            { 'profile.gender': 'man' },
                            { 
                                $or : [{ 'profile.preference' : 'gay' }, 
                                       { 'profile.preference' : 'bi' }] 
                            },
                        ]
                    };

        } else if (user.preference === 'bi') {

            query = {
                    $or: [
                            {
                                $and: [
                                    { 'profile.gender': 'man' },
                                    { 
                                        $or : [{ 'profile.preference' : 'gay' }, 
                                               { 'profile.preference' : 'bi' }] 
                                    },
                                ]
                            },
                            {
                                $and: [
                                    { 'profile.gender': 'woman' },
                                    { 
                                        $or : [{ 'profile.preference' : 'straight' }, 
                                               { 'profile.preference' : 'bi' }] 
                                    }
                                ]
                            }
                        ]
                    };
        }

查询有效,我对它们进行了测试,但我不确定如何动态适应它们。我的猜测是查询也不应该是一个对象,但我不确定如何创建一个有效的变量..

var dbFindQuery = Meteor.users.find({ 
            'profile.invisible': false,
            queryShouldBeHereButObviouslyThisDoesNotWork
        }, {
            fields : {
                'profile.name': 1,
                'profile.city': 1,
                'profile.country': 1,
                'profile.gender': 1,
                'profile.preference': 1,
                'profile.story': 1
            }
        });
        console.log(dbFindQuery.fetch());
        return dbFindQuery;

谁能给我一个正确方向的指针?

【问题讨论】:

    标签: mongodb meteor


    【解决方案1】:

    您当然可以排除常见的查询对象。这是处理它的一种方法:

    Meteor.publish('listprofiles', function() {
      if (!this.userId)
        return [];
    
      var user = Meteor.users.findOne(this.userId);
    
      var gender = user.profile.gender;
      var preference = user.profile.preference;
    
      var straightOrBiWoman = {
        'profile.gender': 'woman',
        'profile.preference': {$in: ['straight', 'bi']}
      };
    
      var gayOrBiMan = {
        'profile.gender': 'man',
        'profile.preference': {$in: ['gay', 'bi']}
      };
    
      var query = {};
    
      if (gender === 'man') {
        switch (preference) {
          case 'straight':
            query = straightOrBiWoman;
            break;
          case 'gay':
            query = gayOrBiMan;
            break;
          default:
            query = {$or: [gayOrBiMan, straightOrBiWoman]};
        }
      }
    
      query['profile.invisible'] = false;
    
      return Meteor.users.find(query, {fields: {profile: 1}});
    });
    

    这里我们根据用户的genderpreference 重用straightOrBiWomangayOrBiMan。请注意,我使用$in operator 来简化查询。我还建议您不要在fields 修饰符中指定二级字段,原因解释为here。最后,我建议测试这段代码,因为在重写它时我可能遗漏了逻辑中的某些内容。希望这个示例能帮助您朝着正确的方向前进。

    【讨论】:

    • 嘿@DavidW 非常感谢您抽出时间再次回答我的一个问题!我从查询中得到一个错误[{'profile.invisible': false}];线虽然。在控制台中,它将(我相信)整个 mongo 对象记录回给我。所以我不确定会发生什么,因为我根本不清楚这个信息。开头: { _mongo: { _observeMultiplexe.......我还认为字段修饰符是必需的,因为我们试图从默认情况下是“安全”的 Meteor.users 集合中获取数据。还是我误会了?
    • 对不起,我的答案有几个错别字;再试一次。另请注意,gender === 'woman' 案例未编写,因此您需要添加该案例,否则所有配置文件都将在该案例中发布。发布用户时非常重要有一个字段修饰符。我是说您不想指定 2 级深度的字段。例如指定“profile”,不要指定“profile.gender”。
    • 啊,太棒了!这节省了大量关于字段修饰符的输入。如果 (!user || !gender || !preference) return; 我添加了一个守卫;在声明这些变量之后。只是想说你在上一个问题中教过我(不确定是否需要)。巨大的登录控制台根本没有帮助。在这种情况下你会怎么做?再次感谢!
    • 哦,顺便说一句,当我记录 return 语句时,它仍然给了我一个巨大的 mongo 对象,但我期望的只是用户。查询确实可以工作!
    猜你喜欢
    • 2018-09-20
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    相关资源
    最近更新 更多