0

我有一个非常大的集合(超过 800k),我需要实现一个基于标签的自动完成(仅基于单词开头)功能的查询。我的文件如下所示:

 {
    "_id": "theid",
    "somefield": "some value",
    "tags": [
        {
            "name": "abc tag1",
            "vote": 5
        },
        {
            "name": "hij tag2",
            "vote": 22
        },
        {
            "name": "abc tag3",
            "vote": 5
        },
        {
            "name": "hij tag4",
            "vote": 77
        }
    ]
}

例如,如果我的查询将针对所有以“ab”开头并具有“somefield”即“some value”的标签,则结果将是“abc tag1”、“abc tag3”(仅名称)。我更关心查询的速度,而不是插入和更新的速度。

我假设聚合框架是正确的方法,但是对于非常快速的查询来说,最好的管道和索引是什么?

这些文档不是“标签”文档,它们是代表客户端对象的文档,它们包含更多数据字段,为简单起见,我省略了,每个客户端都有几个标签和另一个字段(我更改了它的名称,所以它不会与标签混淆大批 )。我需要获得一组客户拥有的所有标签不重复的集合。

4

1 回答 1

0

您的文档结构没有意义 - 我假设tags是一个数组而不是一个对象。尝试这样的查询

db.tags.find({ "somefield" : "some value", "tags.name" : /^abc/ })

上有一个索引{ "maintag" : 1, "tags.name" : 1 }。MongoDB 将左锚正则表达式查询优化为范围查询,可以使用索引有效地完成(参见$regex 文档)。

您可以使用聚合管道仅从此文档结构中获取标签:

db.tags.aggregate([
    { "$match" : { "somefield" : "some value", "tags.name" : /^abc/ } },
    { "$unwind" : "$tags" },
    { "$match" : { "tags.name" : /^abc/ } },
    { "$project" : { "_id" : 0, "tag_name" : "$tags.name" } }
])

索引仅对第一个 $match 有帮助,因此管道的索引与查询的索引相同。

于 2014-09-30T14:58:11.860 回答