Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 针对大量数据的自定义排序算法_Php_Sql Server_Symfony_Solr_Doctrine Orm - Fatal编程技术网

Php 针对大量数据的自定义排序算法

Php 针对大量数据的自定义排序算法,php,sql-server,symfony,solr,doctrine-orm,Php,Sql Server,Symfony,Solr,Doctrine Orm,我有大量数据需要根据搜索查询以特定方式进行排序,但我不确定采用哪种最佳方法 我试图整理的数据是一个课程列表,按学校分组。每门课程由一所学校讲授。每所学校可能属于任意数量的合作关系,这代表了多所学校之间的关系。用户可以通过课程名称搜索任意数量的课程 我需要对数据进行如下排序: 课程按学校分组,每页有10所学校 可以提供用户搜索过的每门课程的学校应首先出现在列表中 在这些结果之后,属于能够容纳用户搜索的所有课程的合作伙伴关系的学校应该出现在彼此旁边 以下是一个例子: A教授历史、法语和英语课程。 B

我有大量数据需要根据搜索查询以特定方式进行排序,但我不确定采用哪种最佳方法

我试图整理的数据是一个课程列表,按学校分组。每门课程由一所学校讲授。每所学校可能属于任意数量的合作关系,这代表了多所学校之间的关系。用户可以通过课程名称搜索任意数量的课程

我需要对数据进行如下排序:

课程按学校分组,每页有10所学校

可以提供用户搜索过的每门课程的学校应首先出现在列表中

在这些结果之后,属于能够容纳用户搜索的所有课程的合作伙伴关系的学校应该出现在彼此旁边

以下是一个例子:

A教授历史、法语和英语课程。 B教法语和数学。 C教授历史。 B和C是合伙企业。 D教授历史

用户搜索历史和法语

A应该首先出现在结果中,包括它的历史和法语课程,因为它可以提供用户想要的两种课程

B、 然后是C,后面列出了它所教授的相关课程,因为合作关系可以提供用户的两门必修课程

D出现在下一页,因为它只提供1门相关课程

数据跨几个表存储在Microsoft SQL Server数据库中。以下是一个简化的模式:

课程:

整数id varchar名称 国际学校ID 学校:

整数id varchar名称 伙伴关系:

整数id varchar partnershipName 学校伙伴关系:

整数id 国际学校ID int partnershipId 有超过10万门课程和大约300所学校。我不知道如何按照SQL中的规定对课程进行排序,我认为这是我最大的问题。我只需要每页显示10个结果,但由于我不能在SQL查询中进行排序,我必须提取整个结果集并在PHP中手动排序,然后才能将结果集缩减为10个结果

我目前正在使用Doctrine 2通过多个连接在单个查询中提取所需的数据,将结果作为一个数组进行水合。然后,计划是在PHP中操作这个大的记录数组,以使其进入正确的顺序。由于此数组的大小,我担心此排序过程将非常缓慢,因此我正在寻求有关如何加快此过程的建议,方法如下:

处理SQL查询中的排序。 建议如何在搜索引擎(如Solr)中实现所描述的算法,我对此有一点基本经验,但不执行复杂排序。 如果其他两个选项不可行,建议如何最好地在PHP中执行排序。 编辑:


我在这方面取得了一些进展,特别感谢@Neil。我提出了一个单独的问题,其中包含了我迄今为止的一些进展。

通过匹配课程的数量查找学校很简单:

SELECT schoolId, COUNT(*) AS schoolCount
  FROM Courses
  WHERE name IN ('History', 'French')
  GROUP BY schoolId
如果这是您所需要的全部,您可以按schoolCount DESC订购,以便按您想要的顺序订购

要找到与匹配课程的合作关系,您首先需要找到至少有一所学校拥有该课程的合作关系:

SELECT partnershipId, COUNT(DISTINCT name) AS partnershipCount
  FROM SchoolPartnership
  INNER JOIN Courses ON Course.schoolId = SchoolPartnership.schoolId
  WHERE name IN ('History', 'French')
  GROUP BY partnershipId
请注意,之所以需要DISTINCT,是因为我们不关心合作伙伴中有多少学校开设该课程。如果没有DISTINCT,则可以使用subselect:

SELECT partnershipId, COUNT(*) AS partnershipCount
  FROM (
    SELECT DISTINCT partnershipId, name
      FROM SchoolPartnership
      INNER JOIN Courses ON Course.schoolId = SchoolPartnership.schoolId
      WHERE name IN ('History', 'French'))
  GROUP BY partnershipId
然后,您可以使用上面的第一个和最后一个查询作为与SchoolPartnership的联接中的子选择,按partnershipMatches和schoolMatches的降序排列学校。请注意,我假设所有学校都至少有一所学校合作。我认为最终的查询将如下所示:

SELECT SchoolMatches.schoolID
  FROM (
    SELECT schoolId, COUNT(*) AS schoolCount
      FROM Courses
      WHERE name IN ('History', 'French')
      GROUP BY schoolId
  ) SchoolMatches
  JOIN SchoolPartnership ON SchoolMatches.schoolID = SchoolPartnership.schoolID
  JOIN (
    SELECT partnershipId, COUNT(DISTINCT name) AS partnershipCount
      FROM SchoolPartnership
      INNER JOIN Courses ON Course.schoolId = SchoolPartnership.schoolId
      WHERE name IN ('History', 'French')
      GROUP BY partnershipId
   ) PartnershipMatches ON SchoolPartnership.schoolId = PartnershipMatches.schoolId
   ORDER BY PartnershipMatches.partnershipCount DESC, SchoolMatches.SchoolCount DESC

我们对网站的页面也有类似的问题。我们创建了带有所有参数的特殊非规范化搜索表,以执行无子查询或联接的搜索。所有数据都是重复的,所以当某些内容发生变化时,我们会更新所有非规范化数据。我们使用后台任务来同步数据,所以搜索结果可能在很短的时间内不真实

这可能看起来很复杂,但这是唯一的方法,如果您的数据和请求将成长

filter_var('sgamgee@example.com', FILTER_VALIDATE_EMAIL); // Returns "sgamgee@example.com"

这是一个有效的电子邮件地址。

您是否已经使用了“订购依据”条款?目前没有“订购依据”条款,因为我不完全确定我可以订购什么来实现所需的特定订购。100.000门课程?我猜你有重复的课程,比如300门历史课,600门英语课等等?总共有多少不同的科目?是的,会有重复的课程。我目前正在为每个课程添加一个LIKE子句,以过滤结果,但这显然不能处理排序问题。我不知道不同课程的确切数量,因为我现在手头没有DB。谢谢你的时间,我想这是个很好的选择
很接近我需要的。我主要担心的是,如果一所学校提供两门法语课程,我会使用LIKE而不是=,例如初学者法语和高级法语,这将与提供法语和历史课程的学校得分相等。你能想出一种方法来结合这样一个事实,即每门课程都必须在一所学校或在一个伙伴关系中出现吗?而且,学校可能根本不属于一个伙伴关系,我应该提到这一点。我想我可能会将一些连接更改为左连接来处理这一事实。最后,我不是100%确定这一点,因为我没有测试它,但我认为您的解决方案不能保证合作伙伴中的学校出现在一起。例如,P和Q学校都教法语,R和S学校都教历史:P和R学校是合作伙伴,Q和S学校是合作伙伴。在这种情况下,P和R应在结果中相邻出现,Q和S也应该如此。@ChrisC很抱歉没有提前回复,但我不得不强制重新加载页面,以使我的浏览器能够了解网站的更改。@ChrisC对于没有合作关系的学校,我认为您必须离开加入SchoolPartnership和PartnershipMatches的内部连接,加入SchoolMatches。谢谢您的回复。如果查询结果很慢,我会考虑为此添加一个非规范化的表/视图,但是当我从非规范化的表中提取数据时,我仍然存在数据排序的问题。我觉得我在浪费时间尝试用SQL进行排序。请编辑您的答案并格式化代码以使其可读