Как уже отмечалось, порядок аргументов в массиве предложения $ in не отражает порядок получения документов. Это, конечно, будет естественный порядок или выбранным порядком индекса, как показано.
Если вам нужно сохранить этот порядок, то у вас в основном есть два варианта.
Итак, скажем, что вы сопоставляли значения _id
в своих документах с массивом, который будет передан в $in
как [ 4, 2, 8 ]
.
var list = [ 4, 2, 8 ];
db.collection.aggregate([
// Match the selected documents by "_id"
{ "$match": {
"_id": { "$in": [ 4, 2, 8 ] },
},
// Project a "weight" to each document
{ "$project": {
"weight": { "$cond": [
{ "$eq": [ "$_id", 4 ] },
1,
{ "$cond": [
{ "$eq": [ "$_id", 2 ] },
2,
3
]}
]}
}},
// Sort the results
{ "$sort": { "weight": 1 } }
])
Таким образом, это будет расширенная форма. Что в основном происходит здесь, так это то, что так же, как массив значений передается в $in
, вы также создаете «вложенный» $cond
оператор для проверки значений и назначения соответствующего веса. Поскольку это «весовое» значение отражает порядок элементов в массиве, вы можете передать это значение на этап сортировки, чтобы получить ваши результаты в требуемом порядке.
Конечно, вы действительно «строите» «оператор конвейера в коде, что-то вроде этого:
var list = [ 4, 2, 8 ];
var stack = [];
for (var i = list.length - 1; i > 0; i--) {
var rec = {
"$cond": [
{ "$eq": [ "$_id", list[i-1] ] },
i
]
};
if ( stack.length == 0 ) {
rec["$cond"].push( i+1 );
} else {
var lval = stack.pop();
rec["$cond"].push( lval );
}
stack.push( rec );
}
var pipeline = [
{ "$match": { "_id": { "$in": list } }},
{ "$project": { "weight": stack[0] }},
{ "$sort": { "weight": 1 } }
];
db.collection.aggregate( pipeline );
Конечно, если все это кажется вам полезным для вашей чувствительности, вы можете сделать то же самое, используя mapReduce, который выглядит проще, но, скорее всего, будет работать несколько медленнее.
var list = [ 4, 2, 8 ];
db.collection.mapReduce(
function () {
var order = inputs.indexOf(this._id);
emit( order, { doc: this } );
},
function() {},
{
"out": { "inline": 1 },
"query": { "_id": { "$in": list } },
"scope": { "inputs": list } ,
"finalize": function (key, value) {
return value.doc;
}
}
)
И это в основном полагается на испускаемые «ключевые» значения, находящиеся в «индексном порядке» того, как они встречаются во входе array.
Таким образом, это, по сути, ваши способы поддержания порядка списка входных данных в $in
, когда у вас уже есть этот список в определенном порядке.
Сначала необходимо запросить разрешения.
Вы можете использовать этот пакет: https://pub.dartlang.org/packages/simple_permissions
Это разрешение вы должны добавить в свой файл AndroidManifest.xml
. [ 119]
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
И это перечисление, которое вы должны будете использовать
WriteExternalStorage
Здесь у вас есть пример кода:
https://pub.dartlang.org/packages/simple_permissions#-example-tab-
Не забудьте извлечь путь из Directory
:
final directory = await getApplicationDocumentsDirectory();
final String path = directory.path;
File("$path/savedSettings.json")