2016-02-17 6 views
0

Я очень новичок в MongoDB (только на прошлой неделе только начался интерес). Я пытаюсь что-то выяснить, и я не совсем уверен в том, что терминология будет искать его. Поэтому я решил задать вопрос.MongoDB: Выполнение действий на поле коллекции

Я создал коллекцию под названием Students. Students имеет поля id, name, undergrad (который является логическим), classes (который представляет собой массив) и units (что в 3 раза превышает количество классов, которые имеет учащийся).

Теперь я хотел видеть, как я мог выполнять действия в определенном поле Students. Я сделал это, вставил пару документов и целенаправленно не включил поле units. И я хотел, чтобы $set поле units для каждого документа/студента, у которого не было поля. Я сделал следующее:

var studentDoc = db.students.find({units: {$exists:false}}) 
studentDoc.forEach(function(stu){ 
    db.student.update({_id:stu._id}, {$set:{units:{$size:"$classes"}}}) 
} 
) 

Вопрос 1: Я сделал то, что я сделал, даже отдаленно исправил?

Вопрос 2: Когда я набираю studentDoc после установки var studentDoc, он ничего не печатает. Но когда я пишу

var studentDoc = db.students.find({units:{$exists:false}}).toArray() 

он печатает studentDoc как массив, но до сих пор, кажется, не делать ничего в цикле forEach.

Вопрос 3: Как $set в units поле 3 * (размер классов массива)

Я надеюсь, что было ясно в моем вопросе. Я пробовал поиск в документах MongoDB и Google, но не имел никакой удачи (возможно, из-за отсутствия знаний для поиска правильных вещей).

Любая помощь будет замечательной! Вы можете даже указать мне в правильном направлении, и это будет здорово!

Заранее благодарю вас за помощь!

ответ

1

Я не уверен, почему foreach не попадает. Вы можете сделать то же самое с нижним рабочим кодом.

for(i=0;i<studentDoc.length();i++){ 
    var stud_id = studentDoc[i]._id; 
    var doc = db.students.findOne({"_id":stud_id})["classes"]; 
    if(doc){ 
     var len = doc.length; 
     db.students.update({"_id":stud_id},{$set:{"units":len*3}}) 
    } 
} 

Насколько я знаю, вы не можете использовать запросы $ size: "$" в операторе обновления. вы получите ошибку, как показано ниже:

The dollar ($) prefixed field '$size' in 'units.$size' is not valid for storage. 
+0

Спасибо за ваш ответ. У меня была пара вопросов и разъяснений, если вы не возражаете. 1) В вашем ответе studentDoc не является результатом .toArray(), правильно? 2) Использует ли [[классы]] после запроса извлечь это конкретное поле? 3) Я все еще путаюсь, когда использовать кавычки и когда использовать $. Если бы вы могли помочь мне или указать мне направление, объясняющее их использование, это было бы здорово! Еще раз спасибо! – Aashay

+1

1) его не результат toArray(). 2) да. он будет извлекать только классы. 3) для таких функций, как set, addToSet, inc. вам нужно использовать $. как $ set, $ inc, $ addToSet. эти вещи вы будете изучать день ото дня. –

+0

Я пробовал использовать код, который вы предоставили на studentDoc, но я продолжал получать ReferenceError: studentDoc не определен. Когда я добавил toArray() в инициализацию var studentDoc, ошибка исчезла, и ваш код работал отлично. Вы знаете, почему я получал ошибку, не используя .toArray()? – Aashay

1

Возвращаемое значение db.collection.find() - это курсор.

In the mongo shell, if the returned cursor is not assigned to a variable using the var keyword, the cursor is automatically iterated up to 20 times to access up to the first 20 documents that match the query. To iterate manually, assign the returned cursor to a variable using the var keyword. So

var studentDoc = db.students.find({units: {$exists:false}}) 

Вы должны итератора studentDoc вручную.

Whereas, the cursor.toArray() returns an array that contains all the documents from a cursor. The method iterates completely the cursor, loading all the documents into RAM and exhausting the cursor. Thus

var studentDoc = db.students.find({units:{$exists:false}}).toArray() 

печатает studentDoc в виде массива.

Если вы хотите использовать forEach, здесь cursor.forEach().

db.students.find({units:{$exists:false}}).forEach() 
1
var studentDoc = db.students.find({units: {$exists:false}}) 

здесь studentDoc находится курсор, это не для печати.

вы можете использовать Foreach

studentDoc.forEach(printjson); 

или итератора курсор

while (studentDoc.hasNext()) { 
    printjson(studentDoc.next()); 
} 
Смежные вопросы