Как передать срез int в $in с помощью mgo

У меня возникли проблемы с созданием запроса с использованием функций bson mgo. Я просто пытаюсь сделать {'search_id': {'$in': [1,2,4,7,9]}}, но не могу понять, как это сделать в mgo.

У меня есть фрагмент ints, и я попытался передать его напрямую:

toRemove := []int{1,2,4,7,9}
err = coll.Remove(bson.M{"search_id": bson.M{"$in": toRemove}})

Я видел другой пост, в котором предлагалось использовать []interface{}, но это тоже не работает:

toRemoveI := make([]interface{}, len(toRemove))
for idx, val := range toRemove {
    toRemoveI[idx] = val
}
err = coll.Remove(bson.M{"search_id": bson.M{"$in": toRemoveI}})

Я просмотрел документацию и другие вопросы здесь и на gh, но большинство вопросов, связанных со срезами, похоже, связаны с получением данных в срез, а не с тем, чего я пытаюсь достичь.

Любая помощь будет принята с благодарностью.


person Olly B    schedule 08.03.2017    source источник


Ответы (1)


Ваше первоначальное предложение (передача значения []int) не имеет недостатков, это допустимо.

Проблема в том, что вы используете Collection.Remove(), который находит и удаляет < strong>single документ, соответствующий предоставленному документу селектора. Таким образом, предлагаемое вами решение удалит ровно 1 документ, search_id которого содержится в переданном вами фрагменте. Если такой документ не найден (и сеанс находится в безопасном режиме, см. Session.SetSafe()), возвращается mgo.ErrNotFound.

Вместо этого используйте Collection.RemoveAll(), который находит и удаляет все документы, соответствующие селектору:

toRemove := []int{1,2,4,7,9}
info, err := c.RemoveAll(bson.M{"search_id": bson.M{"$in": toRemove}})

if err != nil {
    log.Printf("Failed to remove: %v", err)
} else {
    log.Printf("Removed %d documents.", info.Removed)
}
person icza    schedule 08.03.2017
comment
Потрясающе, большое спасибо. Я заметил, что он удаляет только один, но подумал, что это сомнительные данные, которые передаются функциям bson. - person Olly B; 08.03.2017