1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
// Test that the $sort stage respects the collation.
(function() {
"use strict";
// In French, words are sometimes ordered on the secondary level (a.k.a. at the level of
// diacritical marks) by the *last* accent difference rather than the first. This is specified
// by the {backwards: true} option.
//
// For example, côte < coté, since the last accent difference is "e" < "é". Without the reverse
// accent weighting turned on, these two words would sort in the opposite order, since "ô" >
// "o".
var frenchAccentOrdering = {collation: {locale: "fr", backwards: true}};
var coll = db.collation_sort;
coll.drop();
assert.writeOK(coll.insert({_id: 1, word1: "pêche", word2: "côté"}));
assert.writeOK(coll.insert({_id: 2, word1: "pêche", word2: "coté"}));
assert.writeOK(coll.insert({_id: 3, word1: "pêche", word2: "côte"}));
assert.writeOK(coll.insert({_id: 4, word1: "pèché", word2: "côté"}));
assert.writeOK(coll.insert({_id: 5, word1: "pèché", word2: "coté"}));
assert.writeOK(coll.insert({_id: 6, word1: "pèché", word2: "côte"}));
assert.writeOK(coll.insert({_id: 7, word1: "pêché", word2: "côté"}));
assert.writeOK(coll.insert({_id: 8, word1: "pêché", word2: "coté"}));
assert.writeOK(coll.insert({_id: 9, word1: "pêché", word2: "côte"}));
// Test that ascending sort respects the collation.
assert.eq([{_id: "pèché"}, {_id: "pêche"}, {_id: "pêché"}],
coll.aggregate([{$group: {_id: "$word1"}}, {$sort: {_id: 1}}]).toArray());
assert.eq(
[{_id: "pêche"}, {_id: "pèché"}, {_id: "pêché"}],
coll.aggregate([{$group: {_id: "$word1"}}, {$sort: {_id: 1}}], frenchAccentOrdering).toArray());
// Test that descending sort respects the collation.
assert.eq([{_id: "pêché"}, {_id: "pêche"}, {_id: "pèché"}],
coll.aggregate([{$group: {_id: "$word1"}}, {$sort: {_id: -1}}]).toArray());
assert.eq([{_id: "pêché"}, {_id: "pèché"}, {_id: "pêche"}],
coll.aggregate([{$group: {_id: "$word1"}}, {$sort: {_id: -1}}], frenchAccentOrdering)
.toArray());
// Test that compound, mixed ascending/descending sort respects the collation.
assert.eq([4, 6, 5, 1, 3, 2, 7, 9, 8],
coll.aggregate([
{$sort: {word1: 1, word2: -1}},
{$project: {_id: 1}},
{$group: {_id: null, out: {$push: "$_id"}}}
])
.toArray()[0]
.out);
assert.eq([1, 2, 3, 4, 5, 6, 7, 8, 9],
coll.aggregate(
[
{$sort: {word1: 1, word2: -1}},
{$project: {_id: 1}},
{$group: {_id: null, out: {$push: "$_id"}}}
],
frenchAccentOrdering)
.toArray()[0]
.out);
// Test that compound, mixed descending/ascending sort respects the collation.
assert.eq([8, 9, 7, 2, 3, 1, 5, 6, 4],
coll.aggregate([
{$sort: {word1: -1, word2: 1}},
{$project: {_id: 1}},
{$group: {_id: null, out: {$push: "$_id"}}}
])
.toArray()[0]
.out);
assert.eq([9, 8, 7, 6, 5, 4, 3, 2, 1],
coll.aggregate(
[
{$sort: {word1: -1, word2: 1}},
{$project: {_id: 1}},
{$group: {_id: null, out: {$push: "$_id"}}}
],
frenchAccentOrdering)
.toArray()[0]
.out);
// Test that sort inside a $facet respects the collation.
const results = coll.aggregate([{
$facet: {
fct: [
{$sort: {word1: -1, word2: 1}},
{$project: {_id: 1}},
{$group: {_id: null, out: {$push: "$_id"}}}
]
}
}],
frenchAccentOrdering)
.toArray();
assert.eq(1, results.length);
assert.eq(1, results[0].fct.length);
assert.eq([9, 8, 7, 6, 5, 4, 3, 2, 1], results[0].fct[0].out);
})();
|