Algolia:显示所有记录,但按相关性排名

Algolia: Show all records but ranked by relevance

我需要根据与特定查询的相关性对数据集中的记录进行排名,但不过滤掉不相关的数据。如果可能的话,我想为此使用 Algolia。

期望排名

假设我有一个水果箱及其地理位置的数据集。

[
  {
    "fruits": ["apple", "orange"],
    "_geoloc": {"lat": 1, "lng": 2}
  },
  {
    "fruits": ["banana", "apple"],
    "_geoloc": {"lat": 8, "lng": 2}
  },
  {
    "fruits": ["banana"],
    "_geoloc": {"lat": 5, "lng": 2}
  },
  {
    "fruits": ["apple", "banana"],
    "_geoloc": {"lat": 8, "lng": 2}
  },
  {
    "fruits": ["orange"],
    "_geoloc": {"lat": 1, "lng": 2}
  }
]

我需要查询数据,以便我 return 所有数据,但按与输入查询的匹配度和与指定地理位置的接近程度进行排名。

因此,如果地理位置是 {"lat": 1, "lng": 2} 并且查询是 apple, banana,则结果排名数据将如下所示:

[
  {
    "fruits": ["apple", "banana"],
    "_geoloc": {"lat": 8, "lng": 2}
  },
  {
    "fruits": ["banana", "apple"],
    "_geoloc": {"lat": 8, "lng": 2}
  },
  {
    "fruits": ["apple", "orange"],
    "_geoloc": {"lat": 1, "lng": 2}
  },
  {
    "fruits": ["banana"],
    "_geoloc": {"lat": 5, "lng": 2}
  },
  {
    "fruits": ["orange"],
    "_geoloc": {"lat": 1, "lng": 2}
  }
]

首先是与查询完全匹配的记录,然后是具有不同词序的记录,然后是具有某些词(但更接近)的记录,最后是没有匹配词的记录。

到目前为止已经试过了

在仪表板中调试

到目前为止,我已经使用 Algolia 中的仪表板来解决这个问题。但是,当这里的愿望是始终显示所有数据(只是排序)时,总是会过滤掉不相关的记录。

使用上述查询策略,它会return类似于:

[
  {
    "fruits": ["apple", "banana"],
    "_geoloc": {"lat": 8, "lng": 2}
  },
  {
    "fruits": ["banana", "apple"],
    "_geoloc": {"lat": 8, "lng": 2}
  }
] 

匹配查询的数据是 returned 但不是其余的。即使缺少关键字的数据也会被删除。

刻面

我考虑过使用 disjunctive faceting 来实现这一点,但这有两个问题:

  1. 我需要在单词查询中进行错字容忍的全文搜索。例如,用户可以添加 "apple" 或 "cooked apples" 的方面,包含 "apple" 的记录仍将排名靠前。相反,"fruits" 数组中的内容没有限制。该数组还可能包含拼写错误或相关但不完全匹配的内容。

  2. 与查询不匹配的记录仍然不会被 returned。使用分面, "orange" 和 "banana" 的记录,只是,在 fruits 数组中仍然不会被 returned.

您可以通过两种方式使用 Algolia 来执行此操作:作为 搜索引擎 或作为 主要数据源 。由于第一个选项是 Algolia 推荐的,我将从这个开始。

使用 Algolia 作为搜索引擎

Algolia 是一个搜索引擎,旨在处理搜索查询和 return 与查询相关的所有记录的 子集

这意味着 Algolia 不打算用作主要数据源:大多数时候引擎 不会 return 您的所有对象 而是与当前查询最相关的。搜索引擎和常规数据库之间的这种差异允许进行所有优化,使 Algolia 如此之快。

在实践中

对于根据内容和位置对所有箱子进行排序的用例,您可以使用 Algolia 来了解哪些箱子与查询相关,然后使用该信息对整个数据集进行排序

例如,您可以从主数据库中获取箱子列表 并且 在 Algolia 中执行查询以检查哪些是最相关的。 然后您将首先显示 Algolia 结果,然后是列表中剩余的板条箱(可能表示 These crates don't contain the fruits you requested (apple banana))。

您可以这样设置索引:

  • 可搜索属性:"fruits"(无序)
  • 排名公式:默认(因此geo标准用于对fruits匹配查询的板条箱进行排名)

Algolia 然后 return 包含查询中每个水果的所有板条箱,按地理邻近度排序。

您也可以使用 removeWordsIfNoResults=allOptional,因此如果用户键入 orange kiwi 并且没有 crate 包含两者,您将获得仅包含 orange 或仅包含 kiwi 的 crate。同样,如果用户键入 kiwi 并且没有 crates 包含它,引擎将 return 所有 crates 简单地按地理位置排序。


使用 Algolia 作为主要数据源

如果您的数据仅存储在 Algolia 中,您可以执行两个查询:第一个查询获取您的所有记录,第二个查询获取相关结果。然后,您可以通过将相关的放在首位来合并它们,并显示结果列表。

在实践中

您将使用 search for getting the relevant results, and browse 以 1000 条为一批次获取所有记录。一旦您拥有两个列表,您只需显示相关的 crates,从第二个列表中删除重复项,然后显示剩余箱子。

索引设置与以前相同,先按内容过滤,然后按地理位置排序。
与第一种方法一样,您也可以使用 removeWordsIfNoResults 从查询中删除单词,直到引擎找到相关结果。