带有构面计数的 Mongo 搜索结果

use*_*370 3 mongodb faceted-search mgo aggregation-framework

我是 Mongo 的新手,我希望使用 mgo 驱动程序在 Go 中实现分面搜索。我需要获取与我的查询匹配的文档以及方面计数。

我当前的实现是执行一个查询来获取文档,然后执行另一个具有相同参数的查询来获取构面计数,但这似乎效率很低。有没有好的方法可以一步完成此操作?

例如,如果我有一系列书籍:

[{
  title: "Book One",
  author: "Author A",
  numPages: 20,
  type: "book"
},
{
  title: "Book Two",
  author: "Author B",
  numPages: 40,
  type: "book"
},
...
...
...
{
  title: "Magazine AA",
  author: "Author A",
  numPages: 10,
  type: "magazine"
}]
Run Code Online (Sandbox Code Playgroud)

首先,我获取与我的查询匹配的文档:

err = books.Find(bson.M{"$and": matches}).All(&results)
Run Code Online (Sandbox Code Playgroud)

然后,我使用聚合管道和 $facet 重复查询以获取构面计数:

err = Pipe([]bson.M{
    {"$match": bson.M{"$and": matches}},
    {"$facet": bson.M{
        "type":     []bson.M{bson.M{"$sortByCount": "$type"}},
        "author":   []bson.M{bson.M{"$sortByCount": "$author"}, 
    }},
}).All(&facets)
Run Code Online (Sandbox Code Playgroud)

我还看到 $out 可以让我将结果写入临时集合,然后我可以用它来确定方面计数,但我不知道这是否更有效。

Wan*_*iar 5

有没有好的方法可以一步完成此操作?

是的,您可以使用分面搜索来添加非分面结果。例如:

pipeline := []bson.M{ 
                {"$match": bson.M{"type": bson.M{"$in": []string{"book", "magazine"}}}},
                {"$facet": bson.M{"type": []bson.M{{"$sortByCount":"$type"}}, 
                                  "author": []bson.M{{"$sortByCount":"$author"}},
                                  "unfaceted": []bson.M{{"$match": bson.M{} }},
                                 },
                           },
            }
err = collection.Pipe(pipeline).All(&resp)
Run Code Online (Sandbox Code Playgroud)

上面unfaceted $match是没有条件的(空),因为第一$match阶段已经过滤到所需的文档子集。

结果如下:

{
  "type": [
    {
      "_id": "book",
      "count": 2
    },
    {
      "_id": "magazine",
      "count": 1
    }
  ],
  "author": [
    {
      "_id": "Author A",
      "count": 2
    },
    {
      "_id": "Author B",
      "count": 1
    }
  ],
  "unfaceted": [
    {
      "_id": ObjectId(".."),
      "title": "Magazine AA",
      "author": "Author A",
      "numPages": 10,
      "type": "magazine"
    },
    {
      "_id": ObjectId(".."),
      "title": "Book Two",
      "author": "Author B",
      "numPages": 40,
      "type": "book"
    },
    {
      "_id": ObjectId(".."),
      "title": "Book One",
      "author": "Author A",
      "numPages": 20,
      "type": "book"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

现在您可以遍历unfaceted部分,而不是发送单独的查询。另请参阅$facet以获取更多示例和运算符的描述。