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

查看:17
本文介绍了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个项目,我用limit和skip来做,效果很好.

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 字段将根据提供的值进行测试,并且 $eqtruefalse 返回 10.

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 的数组条件的数组中的每个项目.所以它只是为每个等于条件创建一个哈希结构,将它传递给一个数组并将其作为 $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天全站免登陆