3

Я разрабатываю веб-приложение с использованием Sails.js и MongoDB. Я должен запросить базу данных и отсортировать результаты с помощью сложной функции. На самом деле это не сложно, но сложнее, чем сортировать по ключу. Я в этом случае, у меня есть эта коллекцияСложный вид с MongoDB + Sails.js

Пользователей

{ user : "Luis", key1 : 23, key2 : 29 }; 
{ user : "Juan", key1 : 53, key2 : 22 }; 
{ user : "Paco", key1 : 26, key2 : 42 }; 

И я triying получить заказ результатов по key1 - key2

Я пробовал различные запросы, имеющие Mongo complex sorting? в счете, но Бесполезное Не помоги мне.

User.find({}).sort(function(doc1,doc2){return doc1.a . doc2.b }) 
.exec(function(err,users){console.log(users)}); 

Я проверил, что этот путь работает нормально в консоли Robomongo (клиент MongoDB GUI).

db.eval(function() { 
    return db.scratch.find().toArray().sort(function(doc1, doc2) { 
     return doc1.a - doc2.a 
    }) 
}); 

Но я не могу реализовать это, используя паруса и ватерлинию. Я бы использовал родную связь, если это необходимо, но я не знаю, как это сделать.

Пожалуйста, помогите мне, спасибо вам большое!

+0

Вы имеете в виду сортировку по-разному между 'key1' и' key2'? –

+0

да, я имею в виду сортировку по разности между клавишами1 и 'ключ2' –

ответ

2

Вам необходимо использовать метод .aggregate(), который обеспечивает доступ к конвейеру агрегации. Первый этап в трубопроводе - это этап $project, в котором вы используете оператор $subtract для возврата разницы «ключ1» и «ключ2».

Последний этап в конвейере - этап $sort, где вы сортируете документы в порядке возрастания, используя { 'diffkey': 1 } или по убыванию { 'diffkey': -1 }.

db.user.aggregate([ 
    { '$project': { 
     'user': 1, 
     'key1': 1, 
     'key2': 1, 
     'diffkeys': { '$subtract': [ '$key1', '$key2' ] } 
    }}, 
    { '$sort': { 'diffkeys': 1 } } 
]) 

Что дает:

{ 
     "_id" : ObjectId("567d112eaac525feef33a5b7"), 
     "user" : "Juan", 
     "key1" : 53, 
     "key2" : 22, 
     "diffkeys" : -31 
} 
{ 
     "_id" : ObjectId("567d112eaac525feef33a5b6"), 
     "user" : "Luis", 
     "key1" : 23, 
     "key2" : 29, 
     "diffkeys" : 6 
} 
{ 
     "_id" : ObjectId("567d112eaac525feef33a5b8"), 
     "user" : "Paco", 
     "key1" : 26, 
     "key2" : 42, 
     "diffkeys" : 16 
} 

Вы можете захотеть, чтобы добавить еще один дополнительный $project к трубопроводу, чтобы отфильтровать diffkey поле из вашего результата запроса, но делать это вызовет падение производительности. И вообще говоря, вы не должны беспокоиться об одном дополнительном поле в результатах запроса.

1

Если вы имеете в виду сортировку по разнице между key1 и key2 Я не думаю, что это можно сделать с помощью простой находки, я думаю, вам нужно будет использовать агрегацию.

Примечание: Я не знаком с Sail.js, так что я напишу запрос в mongoshell и позволяют перевести плыть

db.user.aggregate([ 
{ 
    $project:{ 
     doc: "$$ROOT", 
     sortOrder: { $subtract: ["$key1", "$key2"] } 
    } 
}, 
{ 
    $sort:{ sortOrder: 1} 
} 
]); 

Не уверен, как именно вы хотите, чтобы ваш конечный результат, чтобы посмотреть, поэтому вы можете захотеть добавить еще один проект в конце.

+0

почему« $$ ROOT »? Это единственное, что я вообще не понимаю ... –

+0

@luigonsec '$$ ROOT' - это ссылка на весь анализируемый документ. См. Документы об этом [здесь] (https://docs.mongodb.org/manual/reference/aggregation-variables/). В основном я не знал, какую информацию вы сделали или не захотели в своем окончательном выпуске, поэтому я просто взял все это. –

+1

["$ key1", "key2"] - должно быть ["$ key1", "$ key2"] –