我一直试图解决这个问题两个月了,经历了与其他开发人员无数的头脑风暴会议,但仍未能找到一个好的解决方案。
这个想法 我们正在为会议,公共活动等建立搜索引擎。
数据
我有数万个事件(包括未来和历史)的数据集,具有以下结构:
{
id: 10,
name: "CES",
intervals: [
{
interval_start: "2013-01-01 08:00",
interval_end: "2013-01-15 10:00",
tags_by_type: {
people: [{name: "Eric Schmidt", weight: 20}, ...]
companies: [{name: "Google", weight: 100}, {name: "Microsoft", weight: 100}, ...],
topics: [{name: "Social Networking", weight: 80}, {name: "Internet marketing", weight: 95}, ...],
places: [{name: "Cannes Palace Hotel", weight: 100}, {name: "Cannes", weight: 100}, {name: "France", weight: 100}]
},
tags: ["Eric Schmidt", "Google", "Microsoft", "Social Networking", "Internet Marketing", "Cannes Palace Hotel", "Cannes", "France"]
},
{
interval_start: "2011-01-01 10:00",
interval_end: "2011-01-15 12:00",
tags_by_type: {
people: [{name: "Marissa Meyer", weight: 20}, ...]
companies: [{name: "Yahoo", weight: 100}, {name: "Facebook", weight: 100}, ...],
topics: [{name: "Recruiting", weight: 80}, {name: "Internet marketing", weight: 15}, ...],
places: [{name: "New york", weight: 100}, {name: "USA", weight: 100}]
},
tags: ["Marissa Mayer", "Yahoo", "Facebook", "Recruiting", "Internet marketing", "New york", "USA"]
},
...
],
}
我们使用规范化的MySQL数据库来添加/更新/删除事件和标签,然后我们为各种搜索方案编译各种格式的数据(例如上面的文档)。
问题 我们希望为用户提供可用于点击和过滤事件的菜单,例如:
地点: [建议地点]美国,法国,... [点击浏览所有地点]
人物: [建议的人] Eric Schmidt,Marissa Meyer,... [点击浏览所有人]
主题 [建议主题]网络营销,初创公司,... [点击浏览所有主题]
当前方法
鉴于我们提出的上述文档结构,如果非常简单,使用MongoDb搜索事件:
{"intervals.tags": { $in: [selectedtag1, selectedtag2, selectedtag3]}}
然而,弄清楚哪些标签在标签菜单中进一步显示用户证明是一种痛苦:)假设我们忽略了权重并试图弄清楚最常见的标签,我们尝试了这个:
db.events.aggregate( { $unwind: "$intervals" }, {$unwind: "$intervals.tags"}, {$group: {"_id": "$intervals.tags", "evCount": {$sum:1}}}, {$match: {"evCount": {$lt: TOTAL_COUNT_OF_EVENTS_MATCHING_OUR_SEARCH}}} );
我们也尝试了 仅仅针对菜单问题,我们尝试从标记开始,而不是事件:
"Eric Schmidt" relates to "Google", "Microsoft", "Social Networking", "Internet Marketing", "Cannes Palace Hotel" ... in the interval "2013-01-01 08:00" and "2013-01-01 10:00"
"Google" relates to "Eric Schmidt", "Microsoft" ... in the interval "2013-01-01 08:00" and "2013-01-01 10:00"
...
然后我们将这些关系映射到MySQL表中:
| tag | related tag | event | start time | end time |
----------------------------------------------------------------------------
| Eric Schmidt | Google | CES | 2013-01-01 08:00 | 2013-01-01 10:00 |
| Eric Schmidt | Microsoft | CES | 2013-01-01 08:00 | 2013-01-01 10:00 |
...
并且,假设用户从菜单中选择了SELECTED_TAG_1和SELECTED_TAG_2,尝试使用SELF JOIN查询它,确保间隔匹配:
SELECT a.related_tag FROM tag_relations a JOIN tag_relations b
ON a.related_tag = b.related_tag
AND a.tag = SELECTED_TAG_1 AND b.tag = SELECTED_TAG_2
AND ( (a.start_time < b.start_time AND a.end_time > b.start_time) OR (a.start_time > b.start_time AND a.start_time < b.end_time) )
但有两个问题:
你们有没有想过如何改进这两种方法中的任何一种,或者建议一种新方法?
我知道这不是一个快速的回复,我感谢你花了一百万次的时间来阅读和理解这个问题。
答案 0 :(得分:0)
您遇到的一个问题是,您不可能总是拥有足够的数据来为所有用户选择组合提供至少一个结果。
如果是这样的话,不要让自己变得复杂,为什么不做其他网站所做的事情,只是显示'没有结果等等'然后提供建议。例如,您可以在删除其中一个过滤器时向他们显示用户选择的部分结果,或者您只需向他们提供一个链接即可删除(或汇总)其当前过滤器列表。