Mongo:如何按外部重量分类 [英] Mongo: how to sort by external weight

查看:61
本文介绍了Mongo:如何按外部重量分类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

跟随这个问题 @NeilLunn优美地回答了这,这是我的问题的详细信息.

Following this question which @NeilLunn has gracefully answered, here is my problem in more detail.

这是一组文档,有些具有user_id,有些则没有. user_id代表创建文档的用户:

This is the set of documents, some have user_id some don't. The user_id represent the user who created the document:

{ "user_id" : 11, "content" : "black", "date": somedate }
{ "user_id" : 6, "content" : "blue", "date": somedate }
{ "user_id" : 3, "content" : "red", "date": somedate }
{ "user_id" : 4, "content" : "black", "date": somedate }
{ "user_id" : 4, "content" : "blue", "date": somedate }
{ "user_id" : 90, "content" : "red", "date": somedate }
{ "user_id" : 7, "content" : "orange", "date": somedate }
{ "content" : "orange", "date": somedate }
{ "content" : "red", "date": somedate }
...
{ "user_id" : 4, "content" : "orange", "date": somedate }
{ "user_id" : 1, "content" : "orange", "date": somedate }
{ "content" : "red", "date": somedate }
{ "user_id" : 90, "content" : "purple", "date": somedate }

前端正在拉动页面,所以每个页面将包含10个项目,而我做到了限制和跳过,因此效果很好.

The front end is pulling pages, so each page will have 10 items and I do that with limit and skip and it is working very well.

如果我们有一个登录用户,我想向他显示最新的登录用户文档,根据他与之交互的用户,首先可能会使他更感兴趣.

In case we have a logged in user, I would like to display to that current logged in user documents which he may find more interesting first, based on the users he interacted with.

当前用户可能会发现感兴趣的用户列表按得分排序,并且位于mongo之外.因此,第一个元素是最重要的用户,我想首先显示其文档,而列表中的最后一个用户则最不重要.

The list of users which the current user may find interesting is sorted by score and is located outside of mongo. So the first element is the most important user which I would like to show his documents first, and the last user on the list is the least important.

列表是一个简单的数组,如下所示: [4,7,90,1].

The list is a simple array which looks like this: [4,7,90,1].

创建此用户分数的系统不在mongo中,但是如果有帮助,我可以复制数据.我还可以更改数组以包含分数.

The system which created this user score is not located within mongo, but I can copy the data if that will help. I can also change the array to include a score number.

我要完成的工作如下:

从列表中获取按user_id的重要性排序的文档,因此将首先显示来自user_id 4的文档,然后显示来自user_id 7的文档,依此类推.当列表上没有用户时,我想显示其余文档.像这样:

Get the documents sorted by importance of the user_id from the list, so that documents from user_id 4 will be the first to show up, documents from user_id 7 second and so on. When where are no users left on the list I would like to show the rest of the documents. Like this:

  1. 所有带有user_d:4的文档
  2. 所有带有user_d:7的文档
  3. 所有具有user_d:90的文档
  4. 所有具有user_d:1的文档
  5. 所有其他文档

我应该如何做到这一点?我对mongo的要求太多了吗?

How should I accomplish this? Am I asking too much from mongo?

推荐答案

给出数组[4,7,90,1],您在查询中想要的是这样的:

Given the array [4,7,90,1] what you want in your query is this:

db.collection.aggregate([
   { "$project": {
       "user_id": 1,
       "content": 1,
       "date": 1,
       "weight": { "$or": [
           { "$eq": ["$user_id": 4] }, 
           { "$eq": ["$user_id": 7] }, 
           { "$eq": ["$user_id": 90] }, 
           { "$eq": ["$user_id": 1] }, 
       ]}
   }},
   { "$sort": { "weight": -1, "date": -1 } }
])

那么,对于$or条件中包含的每个项目,都会针对提供的值测试user_id字段,并且$eqtrue0返回10. c8>.

So what that does is, for every item contained in that $or condition, the user_id field is tested against the supplied value, and $eq returns 1 or 0 for true or false.

您对代码执行的操作是针对构建数组条件$or的数组中的每个项目.因此,它只是为每个equals条件创建一个哈希结构,将其传递给数组,并将其作为$or条件的数组值插入.

What you do in your code is for each item you have in the array you build the array condition of $or. So it's just creating a hash structure for each equals condition, passing it to an array and plugging that in as the array value for the $or condition.

我可能应该将$ cond运算符从以前的代码中删除,所以这部分会更加清楚.

I probably should have left the $cond operator out of the previous code so this part would have been clearer.

以下是Ruby Brain的一些代码:

Here's some code for the Ruby Brain:

userList = [4, 7, 90, 1];

orCond = [];

userList.each do |userId|
  orCond.push({ '$eq' => [ 'user_id', userId ] })
end

pipeline = [
    { '$project' => {
        'user_id' => 1,
        'content' => 1,
        'date' => 1,
        'weight' => { '$or' => orCond }
    }},
    { '$sort' => { 'weight' => -1, 'date' => -1 } }
]

如果您希望拥有单独的权重,并且我们假设使用键值对,则需要嵌套$ cond:

If you want to have individual weights and we'll assume key value pairs, then you need to nest with $cond :

db.collection.aggregate([
   { "$project": {
       "user_id": 1,
       "content": 1,
       "date": 1,
       "weight": { "$cond": [
           { "$eq": ["$user_id": 4] },
           10,
           { "$cond": [ 
               { "$eq": ["$user_id": 7] },
               9,
               { "$cond": [
                   { "$eq": ["$user_id": 90] },
                   7,
                   { "$cond": [
                       { "$eq": ["$user_id": 1] },
                       8, 
                       0
                   ]}
               ]}
           ]}
       ]}
   }},
   { "$sort": { "weight": -1, "date": -1 } }
])

请注意,这只是一个返回值,不需要按顺序排列.您可以考虑一下它的产生.

Note that it's just a return value, these do not need to be in order. And you can think about the generation of that.

有关生成此结构的信息,请参见此处:

For generating this structure see here:

https://stackoverflow.com/a/22213246/2313887

这篇关于Mongo:如何按外部重量分类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆