Mongo 个包含分面数的搜索结果
Mongo search results with facet counts
我是 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"
}]
首先我得到与我的查询匹配的文档:
err = books.Find(bson.M{"$and": matches}).All(&results)
然后我使用聚合管道和 $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)
我还看到 $out 可以让我将结果写入一个临时集合,然后我可以用它来确定方面计数,但我不知道这是否更有效。
Is there a good way to do this in a single step?
是的,您可以使用分面搜索来添加未分面的结果。例如:
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)
上面的 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"
}
]
}
现在您可以遍历 unfaceted
部分,而不是发送单独的查询。有关运算符的更多示例和说明,另请参阅 $facet。
我是 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"
}]
首先我得到与我的查询匹配的文档:
err = books.Find(bson.M{"$and": matches}).All(&results)
然后我使用聚合管道和 $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)
我还看到 $out 可以让我将结果写入一个临时集合,然后我可以用它来确定方面计数,但我不知道这是否更有效。
Is there a good way to do this in a single step?
是的,您可以使用分面搜索来添加未分面的结果。例如:
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)
上面的 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"
}
]
}
现在您可以遍历 unfaceted
部分,而不是发送单独的查询。有关运算符的更多示例和说明,另请参阅 $facet。