Другой способ использования запроса агрегирования применим только для версии MongoDB> 3.4 -
. Благодарим вас за это сообщение .
Примеры документов для выбирается в этом порядке -
var order = [ "David", "Charlie", "Tess" ];
Запрос -
var query = [
{$match: {name: {$in: order}}},
{$addFields: {"__order": {$indexOfArray: [order, "$name" ]}}},
{$sort: {"__order": 1}}
];
var result = db.users.aggregate(query);
Еще одна цитата из сообщения, объясняющая эти операторы агрегирования -
Этап «$ addFields» является новым в версии 3.4 и позволяет вам «создавать» новые поля для существующих документов, не зная всех других существующих полей. Новое выражение «$ indexOfArray» возвращает позицию определенного элемента в заданном массиве.
В основном оператор
addToSet
добавляет новое полеorder
в каждый документ, когда он его находит, и это Полеorder
представляет собой первоначальный порядок нашего массива, который мы предоставили. Затем мы просто сортируем документы на основе этого поля.
По крайней мере, укажите, что вы имеете в виду прямых детей, поскольку их может быть несколько, и программа не может понять, что вы имеете в виду:
var one = document.querySelector('div.rules > :nth-child(1)');
var two = document.querySelector('div.rules > :nth-child(2)');
var three = document.querySelector('div.rules > :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
Вот объяснение того, что пошло не так. Это был результат вашего селектора. Странность в том, как он воспроизводился, была вызвана вашей HTML-структурой и использованием querySelector.
div.rules :nth-child()
Сначала будет выбран целевой элемент <div class="rules">
. Затем он будет искать всех элементов, которые являются n-ными дочерними элементами внутри этого div из-за пространства между двумя селекторами. После этого, используя
querySelector
, вы выберете первый элемент соответствующего набора.
Вот почему вы в итоге получили первый <div>
с :nth-child(1)
, потому что он на самом деле соответствовал каждому отдельному nth-child (1), но получение первого результата было совпадением с ожидаемым вами элементом.
Тем не менее, :nth-child(2)
соответствие каждому второму дочернему элементу было слишком широким, и в итоге он получил второго дочернего элемента в первом элементе div, и, поскольку это был первый результат, именно там был красный фон появился.
Последнее любопытство :nth-child(3)
, казалось бы, действительно ударило по нужному элементу, было только потому, что во всем этом html есть только один третий дочерний элемент, и это был тот, который вы ожидали, хотя, как объяснялось по причинам, отличным от предполагаемых .
Вы хотите ориентироваться только на прямых детей из div.rules
. Так как вы используете querySelector
, он возвращает только первый результат, для :nth-child(2)
, это входные данные в первом div (вы заметите, что в вашем примере это красный фон)
[ 116]
var one = document.querySelector('div.rules > :nth-child(1)');
var two = document.querySelector('div.rules > :nth-child(2)');
var three = document.querySelector('div.rules > :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
document.querySelector
вернет один элемент , и, как вы можете видеть, ваш ввод красный, потому что к нему применяется правило div.rules :nth-child(2)
, так как это второй дочерний элемент в его родительском элементе, поэтому вы выберете его ( так как он стоит первым в дереве DOM), а не div.
Вам следует использовать селектор >
, если вы хотите нацелиться только на div, или использовать div:nth-child()
или рассмотреть document.querySelectorAll
, чтобы получить все элементы, соответствующие селектору:
var one = document.querySelector('div.rules > :nth-child(1)');
var two = document.querySelector('div.rules > :nth-child(2)');
var three = document.querySelector('div.rules > :nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
/*this will add border to all inputs and second div*/
var all = document.querySelectorAll('div.rules :nth-child(2)');
for(var i=0;i<all.length;i++) {
all[i].style.border="3px solid green";
}
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
попробуйте так:
var one = document.querySelector('div.rules div:nth-child(1)');
var two = document.querySelector('div.rules div:nth-child(2)');
var three = document.querySelector('div.rules div:nth-child(3)');
one.classList.add('arule');
two.classList.add('brule');
three.classList.add('crule');
.arule {
background-color: yellow;
}
.brule {
background-color: red;
}
.crule {
background-color: blue;
}
<div class="rules">
<div>
<label for="rule1">Rule1</label>
<input id="rule1">
</div>
<div>
<label for="rule2">Rule2</label>
<input id="rule2">
</div>
<div>
<label for="rule3">Rule3</label>
<input id="rule3">
</div>
</div>
Я сделал div.rules div:nth-child(2)