如何在MongoDB中使用字段开始字母(A到Z)获取随机文档?

发布于 2025-01-26 06:21:35 字数 1322 浏览 1 评论 0 原文

我正在尝试与MongoDB合计。我的目标是我想获得随机名称 从给Z的字母A开始。结果,每个单词都以字母开头必须在响应中只有一次,但我不知道该怎么做。我将匹配条件与Regex 样本条件以获取随机文档。

这是我的收藏;

[
  {
    "name": "ahmet"
  },
  {
    "name": "barış"
  },
  {
    "name": "ceyhun"
  },
  {
    "name": "aslan"
  },
  {
    "name": "deniz"
  },
  ....
]

这是我的汇总功能;

db.collection.aggregate([
  {
    $match: {
      name: {
        $regex: "^a|^b|^c" // must be A to Z
      }
    }
  },
  {
    "$sample": {
      "size": 3 // Must be 26
    }
  }
])

我正在等待这样的回应。

[
  {
    "name": "ahmet"
  },
  {
    "name": "barış"
  },
  {
    "name": "ceyhun"
  },
  .... // other words starting with d, e , f but only one word for each letter
]

但是我得到了;

[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "name": "barış"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "name": "aslan"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "name": "ahmet"
  },
  // name => aslan, name => ahmet (Two words starting with same letter)
]

我是MongoDB的新手,如果有人可以在我错了的地方帮助我,我会很感激。

mongo Playground

I'm trying to make an aggregate with mongodb. My goal is that I want to get random names
starting with letters A to Z. As a result, each word starts with letter must be only once in the response but I can't figure out how to do it. I used match condition with regex and sample condition to get random documents.

Here is my collection;

[
  {
    "name": "ahmet"
  },
  {
    "name": "barış"
  },
  {
    "name": "ceyhun"
  },
  {
    "name": "aslan"
  },
  {
    "name": "deniz"
  },
  ....
]

Here is my aggregate function;

db.collection.aggregate([
  {
    $match: {
      name: {
        $regex: "^a|^b|^c" // must be A to Z
      }
    }
  },
  {
    "$sample": {
      "size": 3 // Must be 26
    }
  }
])

I'm waiting response to be like this;

[
  {
    "name": "ahmet"
  },
  {
    "name": "barış"
  },
  {
    "name": "ceyhun"
  },
  .... // other words starting with d, e , f but only one word for each letter
]

But I'm getting;

[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "name": "barış"
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "name": "aslan"
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "name": "ahmet"
  },
  // name => aslan, name => ahmet (Two words starting with same letter)
]

I'm newbie at mongodb and if anyone can help me where I'm wrong, I'll be appreciate.

Mongo Playground

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风为裳 2025-02-02 06:21:35

您可以做类似的事情:

编辑带有后卫改进建议*(使用 $ subStrcp $ ifnull ):

db.collection.aggregate([
  {
    $group: {
      _id: {$substrCP: ["$name", 0, 1]},
      name: {$push: "$name"}
    }
  },
  {
    $project: {_id: 0,
      name: {
        $arrayElemAt: [
            "$name", 
            {$toInt: {$multiply: [{$rand: {}}, {$size: {$ifNull: ["$name",[]] }}]}
          }
        ]
      }
    }
  }
])

您可以在这个游乐场示例。

$ group 将保留每个 firstL 的名称列表, $ arryelemat 带有 $ rand 将保持只有一个随机项目。

*感谢@mbay和@paul的改进建议

You can do something like this:

Edit with guard improvement suggestions* (using $substrCP, $ifNull):

db.collection.aggregate([
  {
    $group: {
      _id: {$substrCP: ["$name", 0, 1]},
      name: {$push: "$name"}
    }
  },
  {
    $project: {_id: 0,
      name: {
        $arrayElemAt: [
            "$name", 
            {$toInt: {$multiply: [{$rand: {}}, {$size: {$ifNull: ["$name",[]] }}]}
          }
        ]
      }
    }
  }
])

As you can see on this playground example.

The $group will keep a list of names per each firstL, the $arryElemAt with the $rand will keep only a random item.

*Thanks to @Mbay and @Paul for the improvement suggestions

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文