Fir*_*ari 13 mongodb faceted-search
我正在考虑将MongoDB用于我的下一个项目.此应用程序的核心要求之一是提供方面搜索.有没有人尝试使用MongoDB实现方面搜索?
我有一个产品型号,具有各种属性,如大小,颜色,品牌等.在搜索产品时,此Rails应用程序应在侧栏上显示构面过滤器.Facet过滤器看起来像这样:
Size:
XXS (34)
XS (22)
S (23)
M (37)
L (19)
XL (29)
Color:
Black (32)
Blue (87)
Green (14)
Red (21)
White (43)
Brand:
Brand 1 (43)
Brand 2 (27)
Run Code Online (Sandbox Code Playgroud)
Sam*_*cía 19
我认为使用Apache Solr或ElasticSearch可以获得更大的灵活性和性能,但使用聚合框架支持这一点.
使用MongoDB的主要问题是你需要查询N次:首先获得匹配的结果,然后每组一次; 使用全文搜索引擎时,您可以在一个查询中获取所有内容.
例
//'tags' filter simulates the search
//this query gets the products
db.products.find({tags: {$all: ["tag1", "tag2"]}})
//this query gets the size facet
db.products.aggregate(
{$match: {tags: {$all: ["tag1", "tag2"]}}},
{$group: {_id: "$size"}, count: {$sum:1}},
{$sort: {count:-1}}
)
//this query gets the color facet
db.products.aggregate(
{$match: {tags: {$all: ["tag1", "tag2"]}}},
{$group: {_id: "$color"}, count: {$sum:1}},
{$sort: {count:-1}}
)
//this query gets the brand facet
db.products.aggregate(
{$match: {tags: {$all: ["tag1", "tag2"]}}},
{$group: {_id: "$brand"}, count: {$sum:1}},
{$sort: {count:-1}}
)
Run Code Online (Sandbox Code Playgroud)
用户使用构面过滤搜索后,您必须添加此过滤器以查询谓词并匹配谓词,如下所示.
//user clicks on "Brand 1" facet
db.products.find({tags: {$all: ["tag1", "tag2"]}, brand: "Brand 1"})
db.products.aggregate(
{$match: {tags: {$all: ["tag1", "tag2"]}}, brand: "Brand 1"},
{$group: {_id: "$size"}, count: {$sum:1}},
{$sort: {count:-1}}
)
db.products.aggregate(
{$match: {tags: {$all: ["tag1", "tag2"]}}, brand: "Brand 1"},
{$group: {_id: "$color"}, count: {$sum:1}},
{$sort: {count:-1}}
)
db.products.aggregate(
{$match: {tags: {$all: ["tag1", "tag2"]}}, brand: "Brand 1"},
{$group: {_id: "$brand"}, count: {$sum:1}},
{$sort: {count:-1}}
)
Run Code Online (Sandbox Code Playgroud)
Mongodb 3.4引入了分面搜索
$ facet阶段允许您创建多面聚合,这些聚合可在单个聚合阶段内跨多个维度或方面表征数据.多面聚合提供多个过滤器和分类,以指导数据浏览和分析.
输入文档仅传递给$ facet阶段一次.
现在,您不需要查询N次以检索N个组上的聚合.
$ facet在同一组输入文档上启用各种聚合,而无需多次检索输入文档.
OP用例的示例查询类似于
db.products.aggregate( [
{
$facet: {
"categorizedByColor": [
{ $match: { color: { $exists: 1 } } },
{
$bucket: {
groupBy: "$color",
default: "Other",
output: {
"count": { $sum: 1 }
}
}
}
],
"categorizedBySize": [
{ $match: { size: { $exists: 1 } } },
{
$bucket: {
groupBy: "$size",
default: "Other",
output: {
"count": { $sum: 1 }
}
}
}
],
"categorizedByBrand": [
{ $match: { brand: { $exists: 1 } } },
{
$bucket: {
groupBy: "$brand",
default: "Other",
output: {
"count": { $sum: 1 }
}
}
}
]
}
}
])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11422 次 |
| 最近记录: |