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

Jac*_*sor 1 search full-text-search ranking algolia

我需要根据与特定查询的相关性对数据集中的记录进行排名,但不能过滤掉不相关的数据.如果可能的话,我想使用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}
  }
]
Run Code Online (Sandbox Code Playgroud)

我需要查询数据,以便返回所有数据,但按匹配排序到输入查询以及与指定地理位置的接近程度.

因此,如果地理定位是{"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}
  }
]
Run Code Online (Sandbox Code Playgroud)

完全匹配查询的记录首先出现,然后记录具有不同的单词排序,然后记录一些单词(但更接近),最后记录没有匹配的单词.

到目前为止尝试过

在仪表板中调试

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

通过上面描述的查询策略,它将返回如下内容:

[
  {
    "fruits": ["apple", "banana"],
    "_geoloc": {"lat": 8, "lng": 2}
  },
  {
    "fruits": ["banana", "apple"],
    "_geoloc": {"lat": 8, "lng": 2}
  }
] 
Run Code Online (Sandbox Code Playgroud)

返回与查询匹配的数据,但不返回其余数据.即使丢失关键字的数据也会被删除.

刻面

我考虑过使用析取面来实现这个目标,但这有两个问题:

  1. 我需要在单词查询中使用拼写错误进行全文搜索.例如,用户可以添加"苹果"或"熟苹果"的方面,并且包含"苹果"的记录仍然是高度排名的.相反,对"fruits"数组中的内容没有限制.该数组也可能包含拼写错误或相关但不完全匹配.

  2. 仍然不会返回与查询不匹配的记录.对于刻面,仅在水果阵列中的"橙色"和"香蕉"的记录仍然不会被返回.

PLN*_*ech 6

有两种方法可以使用Algolia执行此操作:作为搜索引擎或作为主要数据源.作为Algolia推荐的第一个选择,我将从这个开始.

使用Algolia作为搜索引擎

Algolia是一个搜索引擎,它旨在处理搜索查询并返回与查询相关的所有记录的子集.

这意味着Algolia并不打算用作主要数据源:大多数情况下,引擎不会返回所有对象,而是返回当前查询最相关的对象.搜索引擎和常规数据库之间的这种差异允许所有优化使Algolia如此快速.

在实践中

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

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

您可以这样设置索引设置:

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

然后,Algolia将返回包含查询中所有水果的所有包装箱,按地理位置接近排序.

您也可以使用removeWordsIfNoResults=allOptional,如果用户输入orange kiwi并且没有包含两者的箱子,您将获得仅包含orange或仅包含的包kiwi.同样,如果用户键入kiwi并且没有包含它的crate,则引擎将返回所有仅按地理位置排序的包.


使用Algolia作为主要数据源

如果您的数据仅存储在Algolia中,您可以执行两个查询:第一个用于获取所有记录,第二个用于获取相关结果.然后,您可以先将相关的值合并,然后显示结果列表.

在实践中

您将search用于获取相关结果,并browse用于获得1000个批次的所有记录.一旦您有两个列表,您只需显示相关的包装箱,从第二个列表中删除重复项,然后显示剩余的包装箱.

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