您想要的是“分面搜索”结果,您可以在其中保存有关当前结果集中匹配词条的统计信息。随后,虽然有些产品“出现”可以在一个响应中完成所有工作,但您必须考虑到大多数通用存储引擎将需要多次 *** 作。
使用MongoDB,您可以使用两个查询本身获取结果,并使用另一个查询获取构面信息。这将提供与专用搜索引擎产品(例如Solr或ElasticSearch)可用的多方面结果相似的结果。
但是为了有效地执行此 *** 作,您希望以一种可以有效使用它的方式将其包含在文档中。对于您想要的一种非常有效的形式是使用标记化数据数组:
{ "otherData": "something", "facets": [ "country:UK", "city:London-UK", "genre:Student" ] }
因此,“要素”是文档中的单个字段,而不是多个位置。这使得索引和查询变得非常容易。然后,您可以有效地汇总结果,并获取每个方面的总数:
User.aggregate( [ { "$unwind": "$facets" }, { "$group": { "_id": "$facets", "count": { "$sum": 1 } }} ], function(err,results) { });
或更理想的情况是$match
:
User.aggregate( [ { "$match": { "facets": { "$in": ["genre:student"] } } }, { "$unwind": "$facets" }, { "$group": { "_id": "$facets", "count": { "$sum": 1 } }} ], function(err,results) { });
最终给出如下响应:
{ "_id": "country:FR", "count": 50 },{ "_id": "country:UK", "count": 300 },{ "_id": "city:London-UK", "count": 150 },{ "_id": "genre:Student": "count": 500 }
这样的结构很容易遍历和检查诸如离散的“国家”和属于“国家”的“城市”之类的东西,因为该数据始终由连字符“-”分隔。
试图将数组中的文档混搭是一个坏主意。BSON大小限制为16MB,从中将结果混在一起(特别是如果您要保留文档内容),肯定会超出响应范围。
对于像从这样的查询中获得结果的“总计数”这样简单的事情,只需将特定构面类型的元素相加即可。或者只是对
.count()*** 作发出相同的查询参数:
User.count({ "facets": { "$in": ["genre:Student"] } },function(err,count) {});
如此处所述,特别是在实现结果的“分页”时,获取“结果计数”,“实际计数”和实际的“结果页”的角色都被委派给服务器的“分离”查询。
将这些查询中的每一个并行提交到服务器,然后组合一个结构以馈送到您的模板或应用程序,这看上去很像来自提供这种响应的搜索引擎产品之一的多面搜索结果,这没什么错。
总结
因此,在文档中放置一些内容以在各个位置标记构面。标记字符串数组可以很好地达到此目的。它也适用于查询选择形式,例如$in
和,$all
用于方面选择组合上的“或”或“和”条件。
不要仅仅为了匹配某种感知的层次结构而尝试混搭结果或嵌套添加的内容,而要遍历接收到的结果并在令牌中使用简单的模式。这很简单
对内容运行分页查询,作为对方面或总体计数的单独查询。尝试将所有内容推入数组,然后仅进行计数限制是没有意义的。同样的情况也适用于RDBMS解决方案,以执行相同的 *** 作,其中分页结果计数和当前页是单独的查询 *** 作。
在MongoDB博客上有更多有关MongoDB的分面搜索的信息,该信息还介绍了其他一些选项。也有关于使用mongoconnector或其他方法与外部搜索解决方案集成的文章。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)