Использование MongoDB mongo go driver для постоянных коллекций счетчиков [duplicate]

Вот версия 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
}
89
задан numbers1311407 28 September 2013 в 15:11
поделиться

4 ответа

Начиная с 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, а затем выполнить установку только вставки. В обоих случаях документ возвращается.

159
ответ дан numbers1311407 18 August 2018 в 20:37
поделиться
  • 1
    @Gank, если вы используете собственный драйвер mongodb для узла, синтаксис будет больше похож на collection.findAndModify({_id:'theId'}, <your sort opts>, {$setOnInsert:{foo: 'bar'}}, {new:true, upsert:true}, callback). См. документы – numbers1311407 3 June 2014 в 14:12
  • 2
    Есть ли способ узнать, был ли обновлен или вставлен документ? – doom 11 September 2014 в 00:07
  • 3
    Если вы хотите, чтобы проверял, [, что запрос выше (db.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:38
  • 4
    кажется, устарел в аромате findOneAndUpdate, findOneAndReplace или findOneAndDelete – Ravshan Samandarov 4 November 2016 в 13:45
  • 5
    Однако нужно быть осторожным. Это работает только в том случае, если селектор findAndModify / findOneAndUpdate / updateOne однозначно идентифицирует один документ с помощью _id. В противном случае upsert разделяется на сервере в запросе и обновлении / вставке. Обновление все равно будет атомарным. Но запрос и обновление вместе не будут выполняться атомарно. – Anon 25 April 2017 в 20:14

Используя последний драйвер (> версия 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;
0
ответ дан hansmaad 18 August 2018 в 20:37
поделиться

Его немного грязно, но вы можете просто вставить его.

Убедитесь, что ключ имеет уникальный индекс на нем (если вы используете _id, все в порядке, оно уже уникально).

Таким образом, если элемент уже присутствует, он вернет исключение, которое вы можете поймать.

Если он отсутствует, новый документ будет вставлен.

] Обновлено: подробное объяснение этого метода в документации MongoDB

5
ответ дан Joe 18 August 2018 в 20:37
поделиться
  • 1
    хорошо, это хорошая идея, но для ранее существовавшего значения она вернет ошибку, но не само значение, не так ли? – Discipol 3 May 2013 в 15:41
  • 2
    Это на самом деле одно из рекомендуемых решений для изолированных последовательностей операций (find then create if not found, предположительно) docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations – numbers1311407 3 May 2013 в 15:43
  • 3
    @Discipol, если вы хотите сделать набор атомных операций, вы должны сначала заблокировать документ, а затем изменить его и в конце отпустить его. Это потребует больше запросов, но вы можете оптимизировать для наилучшего сценария и делать всего 1-2 запросов в большинстве случаев. см. docs.mongodb.org/manual/tutorial/perform-two-phase-commits – Madarco 3 May 2013 в 16:21

Вот что я сделал (драйвер Ruby MongoDB):

$db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}

Он обновит его, если он существует, и вставьте его, если это не так.

0
ответ дан Vidar 18 August 2018 в 20:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: