Вот версия Swift, если кто-то еще нуждается в ней:
extension IXBezierPath {
// Adapted from : https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Paths/Paths.html#//apple_ref/doc/uid/TP40003290-CH206-SW2
// See also: http://www.dreamincode.net/forums/topic/370959-nsbezierpath-to-cgpathref-in-swift/
func CGPath(forceClose forceClose:Bool) -> CGPathRef? {
var cgPath:CGPathRef? = nil
let numElements = self.elementCount
if numElements > 0 {
let newPath = CGPathCreateMutable()
let points = NSPointArray.alloc(3)
var bDidClosePath:Bool = true
for i in 0 ..< numElements {
switch elementAtIndex(i, associatedPoints:points) {
case NSBezierPathElement.MoveToBezierPathElement:
CGPathMoveToPoint(newPath, nil, points[0].x, points[0].y )
case NSBezierPathElement.LineToBezierPathElement:
CGPathAddLineToPoint(newPath, nil, points[0].x, points[0].y )
bDidClosePath = false
case NSBezierPathElement.CurveToBezierPathElement:
CGPathAddCurveToPoint(newPath, nil, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y )
bDidClosePath = false
case NSBezierPathElement.ClosePathBezierPathElement:
CGPathCloseSubpath(newPath)
bDidClosePath = true
}
if forceClose && !bDidClosePath {
CGPathCloseSubpath(newPath)
}
}
cgPath = CGPathCreateCopy(newPath)
}
return cgPath
}
Начиная с MongoDB 2.4, больше нет необходимости полагаться на уникальный индекс (или любой другой обходной путь) для атомных findOrCreate
подобных операций.
Это благодаря $setOnInsert
оператор , новый для 2.4, который позволяет вам указывать обновления, которые должны выполняться только при вставке документов.
Это, в сочетании с опцией upsert
, означает, что вы можете использовать findAndModify
для достижения атомная findOrCreate
-подобная операция.
db.collection.findAndModify({
query: { _id: "some potentially existing id" },
update: {
$setOnInsert: { foo: "bar" }
},
new: true, // return new doc if one is upserted
upsert: true // insert the document if it does not exist
})
Поскольку $setOnInsert
влияет только на вставленные документы, если существующий документ найден, модификация не будет выполнена. Если документ не существует, он будет поддерживать один с указанным _id, а затем выполнить установку только вставки. В обоих случаях документ возвращается.
Используя последний драйвер (> версия 2), вы будете использовать findOneAndUpdate , поскольку findAndModify
устарел. Новый метод принимает 3 аргумента, объект filter
, update
(который содержит ваши свойства по умолчанию, которые должны быть вставлены для нового объекта) и options
, где вы должны указать операцию upsert.
Используя синтаксис обещания, он выглядит так:
const result = await collection.findOneAndUpdate(
{ _id: new ObjectId(id) },
{
$setOnInsert: { foo: "bar" },
},
{
returnOriginal: false,
upsert: true,
}
);
const newOrUpdatedDocument = result.value;
Его немного грязно, но вы можете просто вставить его.
Убедитесь, что ключ имеет уникальный индекс на нем (если вы используете _id, все в порядке, оно уже уникально).
Таким образом, если элемент уже присутствует, он вернет исключение, которое вы можете поймать.
Если он отсутствует, новый документ будет вставлен.
] Обновлено: подробное объяснение этого метода в документации MongoDB
Вот что я сделал (драйвер Ruby MongoDB):
$db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}
Он обновит его, если он существует, и вставьте его, если это не так.
collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback)
. См. документы – numbers1311407 3 June 2014 в 14:12db.collection.findAndModify({query: {_id: "some potentially existing id"}, update: {$setOnInsert: {foo: "bar"}}, new: true, upsert: true})
) вставляет (upsert) ed документ, вы должны рассмотреть возможность использованияdb.collection.updateOne({_id: "some potentially existing id"}, {$setOnInsert: {foo: "bar"}}, {upsert: true})
. Он возвращает{"acknowledged": true, "matchedCount": 0, "modifiedCount": 0, "upsertedId": ObjectId("for newly inserted one")}
, если документ вставлен,{"acknowledged": true, "matchedCount": 1, "modifiedCount": 0}
, если документ уже существует. – K._ 18 July 2016 в 11:38findOneAndUpdate
,findOneAndReplace
илиfindOneAndDelete
– Ravshan Samandarov 4 November 2016 в 13:45