阿尔戈利亚:如何将优化从前端传递到后端?

时间:2019-09-16 22:03:19

标签: algolia

我有一个使用Algolia的React InstantSearch的网页。它具有搜索栏和一些改进。

我希望用户能够按一个按钮并获得所有匹配结果的列表。

要获取所有所有结果的列表,我需要使用Browse Index而不是Search Index。浏览索引允许检索所有匹配;搜索索引最多只能检索1000个匹配。但是,不应在用户界面中使用浏览索引。因此,我想在我的Web服务器上创建一个使用浏览索引的API端点,以便在给定搜索查询的情况下返回匹配命中的列表。

对于搜索查询,我能够成功完成此操作,但是我不知道如何进行优化。

这是我到目前为止的概况。

后端(在Ruby中):

ALGOLIA_INDEX = Algolia::Index.new('Products')

class AlgoliaSearchController < ActionController::Base
  def get_search_results
    query = params['query']
    hits = []
    ALGOLIA_INDEX.browse({query: query}) do |hit|
      hits << hit
    end
    render json: hits
  end
end

前端:

import qs from 'qs';
import React, { useCallback, useState } from 'react';
import { InstantSearch } from 'react-instantsearch-dom';

function getSearchResults(query) {
  const queryString = qs.stringify({
    query,
  })
  return fetch(`/search_results?{queryString}`);
}


function App() {
  const [searchState, setSearchState] = useState(null);
  const onSearchStateChange = useCallback(searchState => {
    setSearchState(searchState);
  }, [searchState]);
  const onClick = useCallback(() => {
    console.log(getSearchResults(searchstate.query));
  });

  return (
    <InstantSearch ... onSearchStateChange={onSearchStateChange}>
      <button onClick={onClick}>Search</button>
    </InstantSearch>
  );
}

我找不到任何资源来解释如何进行优化搜索。

到目前为止我看过的东西:

  • 我可以尝试将searchState format映射到浏览索引所使用的Search API Parameters。我可以从搜索状态到查询编写自己的映射器,但是,1)这看起来很复杂,我怀疑缺少了一些简单的东西; 2)这似乎应该在某个地方开源,因为我怀疑我不是首先遇到这个问题。

  • 有一篇文章Backend InstantSearch ,它说明了如何编写可以插入InstatSearch组件中的后端。但是,这并不能解释我如何从搜索状态进行一次性搜索。

1 个答案:

答案 0 :(得分:8)

您说对了,这目前还不是很简单。获取可用于“浏览”的原始搜索参数的流程如下:

  1. 授予您自定义组件访问最近搜索结果的权限
  2. 从这些结果中读取状态
  3. 使用此状态创建新的helper
  4. 使用helper.getQuery()获取要应用的查询参数

说明此情况的沙箱为:https://codesandbox.io/s/extending-widgets-luqd9

import React, { Component } from 'react';
import algoliaHelper from 'algoliasearch-helper';
import { connectStateResults } from 'react-instantsearch-dom';

class Downloader extends Component {
  state = {
    instructions: '',
  };

  onDownloadClick = () => {
    // get the current results from "connectStateResults"
    const res = this.props.searchResults;
    // read the private "state" (SearchParameters) from the last results
    const state = res && res._state;
    // create a new "helper" with this state
    const helper = algoliaHelper({}, state.index, state);
    // get the query parameters to apply
    const rawQuery = helper.getQuery();
    this.setState({
      instructions:
        'Do a search backend with this:\n\nclient.browseAll(' +
        JSON.stringify(rawQuery, null, 2) +
        ')',
    });
  };

  render() {
    return (
      <React.Fragment>
        <button onClick={this.onDownloadClick}>download</button>
        <pre>{this.state.instructions}</pre>
      </React.Fragment>
    );
  }
}

export default connectStateResults(Downloader)