Reputation: 1
I'm look to sort results based on in which field matches. Given I have a collection with documents like this:
{
"foo": "orange",
"bar": "apple",
"baz": "pear",
}
{
"foo": "kiwi",
"bar": "orange",
"baz": "banana",
}
How can I sort a result for documents matching "orange" in either foo, bar, or baz by the field in which they match, i.e. all documents matching on field foo should appear in the result before documents in field bar etc.?
Thanks!
Upvotes: 0
Views: 1679
Reputation: 2569
You want a list of documents in the following order:
This can not be done with a single find().sort() command, because there is no way to sort by the key (name) of a field, only by it's content.
It is possible, though, with an aggregate():
> db.xx.find()
{ "_id" : 1, "bar" : "apple", "baz" : "pear", "foo" : "orange" }
{ "_id" : 2, "foo" : "banana", "bar" : "apple", "baz" : "orange" }
{ "_id" : 3, "foo" : "banana", "bar" : "orange", "baz" : "pear" }
{ "_id" : 4, "foo" : "banana", "bar" : "apple", "baz" : "pear" }
{ "_id" : 5, "foo" : "orange", "bar" : "apple", "baz" : "pear" }
> db.xx.aggregate([
... { $match: { $or: [ { foo: "orange" }, { bar: "orange" }, { baz: "orange" } ] } },
... { $project: { "_id": 1,
... "which": { "$cond": [{ "$eq": [ "$foo", "orange" ]}, "01foo",
... { "$cond": [{ "$eq": [ "$bar", "orange" ]}, "02bar", "03baz" ] }
... ] }
... } },
... { $group: { _id: { which: "$which", _id: "$_id" } } },
... { $sort: { "_id.which": 1, "_id._id": 1 } },
... { $project: { which: { $substr: ["$_id.which", 2, -1] }, _id: "$_id._id" } },
... ]);
{
"result" : [
{
"_id" : 1,
"which" : "foo"
},
{
"_id" : 5,
"which" : "foo"
},
{
"_id" : 3,
"which" : "bar"
},
{
"_id" : 2,
"which" : "baz"
}
],
"ok" : 1
}
You're right, if you think that is aggregate is too complicated. It would be easier if your data were organized differently, something like
{ type: "foo", value: "orange" }
and have the type names sortable - like "ba1","ba2","ba3" instead of "foo","bar","baz"
For more information on aggregate, see http://docs.mongodb.org/manual/reference/aggregation and http://docs.mongodb.org/manual/tutorial/aggregation-examples/
Upvotes: 1
Reputation: 3554
Try below query:
db.test.find({$or:[{'foo':"orange"},{'bar':"orange"}]}).sort({'foo':-1,'bar':-1})
Upvotes: 0