【问题标题】:mongoDB $sort inconsistent resultsmongoDB $sort 结果不一致
【发布时间】:2018-01-01 01:30:50
【问题描述】:

我在 go lang 中有以下查询,效果很好:

query["name"] = bson.M{"$regex": searchStr, "$options": "i"}
query["likes"] = userSession.Id
c.Find(query).Skip(0).Limit(2).Select(bson.M{"name":1, "profile":1, "description":1, "user_id":1, "likes":1}).Sort("-pro", "-check").All(&business);

然后我尝试使用聚合框架编写相同的查询:

query["name"] = bson.M{"$regex": searchStr, "$options": "i"}
query["likes"] = userSession.Id
oe := bson.M{
    "$match" :query,
}
oa := bson.M{
    "$project": bson.M {"pro": 1, "check": 1, "name":1, "profile":1, "description":1, "user_id":1, "likes":1, "nrLikes": bson.M{ "$size": "$likes" }, "city": 1, "country": 1, "industry": 1},
}
ol := bson.M{
    "$limit" :pageSize,
}
os := bson.M{
    "$skip" :skips,
}
or := bson.M{
    "$sort" : bson.M {"pro": -1, "check": -1},
}

pipe := c.Pipe([]bson.M{oe, oa, or, os, ol  })

pipe.All(&business)

第二个查询在 90% 的情况下都能正常工作,但在 10% 的情况下它返回的结果顺序不同。

有什么想法吗?

稍后编辑:这是结果

[]bson.M{
{
    "description": "<p>sasdfdasf</p>",
    "profile":     []interface {}{
        "rKwMmXPWheGczwvGn2TzSRU7jRorhorKwMmXPWheGczwvGn2TzSRU7jRorho=0.jpg",
    },
    "likes": []interface {}{
        "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    },
    "nrLikes":  int(1),
    "name":     "ediloc.com2",
    "city":     "Calimanesti",
    "industry": "Automotive",
    "_id":      "Yo\xd4f\x1a\xa9Q|w\tG^",
    "user_id":  "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    "country":  "Romania",
},
{
    "_id":         "Yo\xc7\xd7\x1a\xa9Qy1['\xea",
    "user_id":     "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    "name":        "ediloc.com",
    "country":     "Romania",
    "description": "<p>a</p>",
    "profile":     []interface {}{
        "1ssSySNRZwGJJwqzXghL6qzAVfWZis1ssSySNRZwGJJwqzXghL6qzAVfWZis=1.jpg",
    },
    "likes": []interface {}{
        "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    },
    "nrLikes":  int(1),
    "city":     "Calimanesti",
    "industry": "Accounting",
},
}


[]bson.M{
{
    "likes": []interface {}{
        "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    },
    "_id":     "Yo\xd4f\x1a\xa9Q|w\tG^",
    "name":    "ediloc.com2",
    "city":    "Calimanesti",
    "country": "Romania",
    "profile": []interface {}{
        "rKwMmXPWheGczwvGn2TzSRU7jRorhorKwMmXPWheGczwvGn2TzSRU7jRorho=0.jpg",
    },
    "user_id":     "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    "industry":    "Automotive",,
    "nrLikes":     int(1),
},
{
    "_id":      "Yo\xc7\xd7\x1a\xa9Qy1['\xea",
    "user_id":  "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    "industry": "Accounting",
    "profile":  []interface {}{
        "1ssSySNRZwGJJwqzXghL6qzAVfWZis1ssSySNRZwGJJwqzXghL6qzAVfWZis=1.jpg",
    },
    "likes": []interface {}{
        "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    },
    "nrLikes":     int(1),
    "name":        "ediloc.com",
    "city":        "Calimanesti",
    "country":     "Romania",
    "description": "<p>a</p>",
},
}


[]bson.M{
{
    "nrLikes":     int(1),
    "user_id":     "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    "description": "<p>a</p>",
    "profile":     []interface {}{
        "1ssSySNRZwGJJwqzXghL6qzAVfWZis1ssSySNRZwGJJwqzXghL6qzAVfWZis=1.jpg",
    },
    "country":  "Romania",
    "industry": "Accounting",
    "likes":    []interface {}{
        "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    },
    "_id":  "Yo\xc7\xd7\x1a\xa9Qy1['\xea",
    "name": "ediloc.com",
    "city": "Calimanesti",
},
{
    "name":        "ediloc.com2",
    "industry":    "Automotive",
    "description": "<p>sasdfdasf</p>",
    "likes":       []interface {}{
        "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    },
    "user_id": "Yo\xc7;\x1a\xa9Qy\b\xb8\xa2\xf9",
    "city":    "Calimanesti",
    "country": "Romania",
    "profile": []interface {}{
        "rKwMmXPWheGczwvGn2TzSRU7jRorhorKwMmXPWheGczwvGn2TzSRU7jRorho=0.jpg",
    },
    "nrLikes": int(1),
    "_id":     "Yo\xd4f\x1a\xa9Q|w\tG^",
},
}

pro 和 check 字段都是 in32,pro 字段编号较高的文档应该优先于 check 字段较高的文档。

【问题讨论】:

  • pro 字段的数据类型是什么?您能否包含一些排序不正确的示例输出?如果结果不可预测,则很可能您有混合数据类型,这些数据类型根据 BSON Comparison/Sort Order 排序。
  • @Stennie 我编辑了我的问题并添加了输出。 check 和 pro 字段也是 int32。并继续发现使用 cursor.sort() 的第一个查询工作正常。
  • 你改变了输出吗?除非我遗漏了什么,否则当前结果文档似乎没有您要排序的 procheck 字段。
  • 我只是这次没有把它们放在项目中。
  • 可以看这里2message.com:8080/search/business?q=e如果多次刷新页面,结果不一致。一个文档有 pro:1 和 check:0,另一个文档有 pro:0 和 check:1

标签: mongodb go database


【解决方案1】:

确保您有您的排序管道阶段之前您的限制和跳过阶段。您只能通过限制/跳过排序输入可靠地获得相同的结果。

编辑

意识到您正在使用bson.M {"pro": -1, "check": -1} 来定义您的排序顺序。地图的迭代顺序在 Go 中是未指定的,并且可以更改。因此,这可能就是您得到不一致结果的原因。

尝试将其更改为 bson.D,以便保持要排序的列的顺序。

这有助于查看查询 Sort 方法如何根据您提供的字符串构造它。

对于您的用例,您可以将 or 变量更改为:

or := bson.M{
    "$sort": bson.D{
        bson.DocElem{Name: "pro", Value: -1},
        bson.DocElem{Name: "check", Value: -1},
     },
}

【讨论】:

  • 是的,我在跳过和限制之前进行排序。
  • 对不起,你确实是。我只是阅读了声明顺序,而不是它们传递给c.Pipe 的顺序。顺便说一句,建议在跳过之前进行限制(请参阅this previous question)。不过,不要认为这会是你的问题。
  • 我现在试过了,但没有任何改变。一个文档有 pro:1 和 check:0,另一个有 pro:0 和 check:1 你可以在这里看到:2message.com:8080/search/business?q=e 如果你多次刷新页面
  • 更新了我的答案,看看是否有帮助
  • 我没用过bson.D,上面几行应该怎么写?我试过了:or := bson.D{ "$sort" : []bson.D{ {Name: "pro", Value: -1}, {Name: "check", Value: -1} } 但没有编译
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多