我正在尝试设计一个与AppEngine Search API(java)一起使用的好架构,并且在下列用例的情况下会喜欢一些意见:
在我们的应用程序中,我们希望用户能够搜索Foo类型的对象。 Foo对象看起来像:
{
groupId: "x1",
name: "somename"
someFieldA: "somevalue",
someFieldB: "somevalue",
someFieldC: "somevalue"
}
但是,不同的Foo对象可能如下所示:
{
groupId: "x2",
name: "somename"
someFieldD: "somevalue",
someFieldE: "somevalue",
someFieldF: "somevalue"
}
群组ID非常重要:
因此,我想要解决的用例是,用户应该能够搜索Foo(通过其任何字段),因为他们只能访问某些Foo。以下是两个都有缺点的解决方案:
解决方案1:
userquery AND (groupId:X OR groupId:Y OR groupId:Z)
解决方案2:
似乎解决方案2是最理想的 - 但我无法弄清楚如何解决结果问题的组合/排名。
有什么想法吗?
- 更新1 -
以下是文档内容的更具体的示例:
{
groupId:"Hiring Process",
name: "Bob Smith",
position: "Software Engineer",
yearsOfExperience: 6
}
{
groupId:"Sales Process",
name: "Frank J",
company: "Engineering Engineer Inc.",
contactInfo: "555-555-5555"
}
{
groupId:"Hiring Process",
name: "Jane Doe",
position: "Marketing",
yearsOfExperience: 3
}
{
groupId:"Sales Process",
name: "Jane Moe",
company: "Google",
contactInfo: "666-666-6666"
}
如上所示,这些文件代表了人们。每个对象的组ID为“Sales Process”或“Hiring Process”。请注意,文档的字段根据它们具有的groupId而不同。我们系统中的单个用户可以访问有关这两个进程中所有人的所有信息。
因此,假设我们的用户搜索engineer
,应该返回2个结果,1个用于Bob Smith
,1个用于Frank J
。但是,Frank J
结果应该排名/得分更高,因为“工程师”一词在文档中出现两次。
因为所有文档的字段数量的超集可能具有> 1000的大小,所以我认为我不能将所有文档放在1个索引中。如果我对索引进行分片(每组ID为1),我如何在多组搜索结果中排名/得分?
* - 更新2 -
我们超过1000字段限制的原因是因为Foo对象的模式是用户可配置的。例如,用户可以创建一个名为“Sales Process”的groupId,并添加一些用户定义的字段,如“lead source”,“product interest”,“close date”等。
由于每个用户都可以在数百万用户中自定义他们的群组,因此所有字段的超集肯定都是> 1000。上面列出的示例Foo对象有点简单。 groupId实际上是一个Id,指向用户创建的所有自定义字段的架构。 foo对象实际上包含这些字段的值。
答案 0 :(得分:2)
这是一个半生不熟的“答案”。我的希望是,它可以激发你的思考,足以让你想出一个能够运作良好的真实答案。
对我来说,基于用户输入动态定义模式(即字段名称集)的概念是一个红色标记。我可能不愿意做一个全面的声明,即一个人应该从不做这样的事情。但它似乎值得再次考虑。
如果字段是用户定义的,那么似乎可能没有系统可以对它们施加的特定处理知识。换句话说,对于系统,字段必须只是通用信息容器。你同意吗?
所以,我的想法会朝着消除这方面的方向发展,无论如何。
我想知道是否有一种方法可以使实际字段名称通用(例如,UserField1,UserField2等),并将用户提供的字段名称的per-groupId映射存储到实际字段名称。似乎这对于全局搜索(搜索查询没有提到字段名称)可以正常工作。
我确实认识到用户不能简单地编写像[engineer yearsOfExperience> 3]这样的查询。但是,想一想,他们还能这样做吗?您是否允许他们定义用户定义字段的类型?
无论如何,我的意思是这些“领域”被不恰当地考虑在内。不知何故,用户定义的字段名称希望存储为数据,而不是用作动态模式。