Пн go выборка размером 1 из 31 всегда возвращает одну и ту же запись - PullRequest
0 голосов
/ 17 июня 2020

Связанный вопрос: Случайная запись из MongoDB

У меня есть агрегатный конвейер (в go, но я надеюсь, что это не актуально) следующим образом:

    freenets, freeerr := collection.CountDocuments(ctx, bson.M{"cluster_id": nil})
    if freeerr != nil || freenets == 0 {
        return nil, errors.Wrap(freeerr, "could not find a random free subnet")
    }

    // Find a random subnet
    matchStage := bson.D{{"$match", bson.D{{"cluster_id", nil}}}}
    sampleStage := bson.D{{"$sample", bson.D{{"size", 1}}}}
    cursor, perr := collection.Aggregate(ctx, mongo.Pipeline{matchStage, sampleStage}, &options.AggregateOptions{})
    if perr != nil {
        return nil, errors.Wrap(perr, "could not find a random free subnet")
    }
    var results []bson.M
    cursor.All(ctx, &results)
    cursor.Close(ctx)
    if len(results) == 0 {
        return nil, errors.Wrap(perr, "could not find a random free subnet")
    }

    subnetRec := results[0] // sample 1, should only be 1 document
    logger.Debugf("Attempting to aquire subnet: %v out of %v random subnets available", subnetRec["_id"], freenets)

Повторные запуски этого кода всегда возвращают один и тот же документ (сначала выполняется подсчет, чтобы показать количество документов):

{"level":"debug","msg":"Attempting to aquire subnet: 10.128.36.32/27 out of 31 random subnets available","requestId":"264b6d80-bf27-4250-8dda-8f9ea30393f7","time":"2020-06-17T12:46:46Z"}
{"level":"debug","msg":"Attempting to aquire subnet: 10.128.36.32/27 out of 31 random subnets available","requestId":"54a4683d-ffe7-4637-8ebd-a4802e3e7b61","time":"2020-06-17T12:49:36Z"}
{"level":"debug","msg":"Attempting to aquire subnet: 10.128.36.32/27 out of 31 random subnets available","requestId":"43637530-5182-40a2-875d-da21817a1539","time":"2020-06-17T12:52:39Z"}
{"level":"debug","msg":"Attempting to aquire subnet: 10.128.36.32/27 out of 31 random subnets available","requestId":"c12c1c06-9a63-4e15-ad5e-6dc1acdaecc9","time":"2020-06-17T12:48:05Z"}
{"level":"debug","msg":"Attempting to aquire subnet: 10.128.36.32/27 out of 31 random subnets available","requestId":"94f0cd8c-3a1e-48b0-9ec6-7a5abd8507b8","time":"2020-06-17T12:51:08Z"}

Я знаю, что документы разные. Что-то не так с моим пониманием $ SAMPLE? Он говорит, что когда образец составляет менее 5% документов, он собирает все, выполняет случайную сортировку, затем выбирает 1: https://docs.mongodb.com/manual/reference/operator/aggregation/sample/

EDIT: также кажется связанным: Агрегирование образцов CosmosDB $ всегда дает один и тот же результат

1 Ответ

0 голосов
/ 17 июня 2020

Я получаю случайные результаты.

MongoDB Enterprise ruby-driver-rs:PRIMARY>  db.foo.insert([  
... 
... { "_id" : 1, "name" : "dave123", "q1" : true, "q2" : true },
... { "_id" : 2, "name" : "dave2", "q1" : false, "q2" : false  },
... { "_id" : 3, "name" : "ahn", "q1" : true, "q2" : true  },
... { "_id" : 4, "name" : "li", "q1" : true, "q2" : false  },
... { "_id" : 5, "name" : "annT", "q1" : false, "q2" : true  },
... { "_id" : 6, "name" : "li", "q1" : true, "q2" : true  },
... { "_id" : 7, "name" : "ty", "q1" : false, "q2" : true  },
... 
... ])
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 7,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})
MongoDB Enterprise ruby-driver-rs:PRIMARY> 
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 7, "name" : "ty", "q1" : false, "q2" : true }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 7, "name" : "ty", "q1" : false, "q2" : true }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : ObjectId("5edc9a5cc18c1cb29a4c752f"), "hai" : "hai" }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 2, "name" : "dave2", "q1" : false, "q2" : false }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 5, "name" : "annT", "q1" : false, "q2" : true }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 1, "name" : "dave123", "q1" : true, "q2" : true }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 7, "name" : "ty", "q1" : false, "q2" : true }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : 3, "name" : "ahn", "q1" : true, "q2" : true }
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$sample:{size:1}}])
{ "_id" : ObjectId("5ede994bcc8cfdfdb6ab6cfa"), "name" : "Goldie" }

CosmosDB не является MongoDB, его поведение не влияет на работу MongoDB.

...