javascript - 如何获取 ReactiveList 中的所有结果

标签 javascript reactjs elasticsearch react-native reactivesearch

我尝试对所有数据使用,但它不起作用,因为我只能获得“大小”参数中所述的结果数量。这是我的代码的一部分。

<ReactiveList
  componentId="results"
  dataField="original_title"
  size={1}
  showResultStats={true}
  pagination={true}
  react={{
    and: "searchbox"
  }}
  onAllData={this.onAllData}
/>

onAllData(shops) {
  let result = null;
  if (shops !== null) {
    console.log(shops.length);
    result = shops.map((marker) => (
      <ListItem>
        <Thumbnail square size={80} source={{ uri: 'https://dummyimage.com/80x80/000/fff' }} />
        <Body>
        <Text>{marker.name}</Text>
        <Text note>{marker.dis}</Text>
        </Body>
      </ListItem>
    ))
    return result;
  }
}

最佳答案

有几种方法可以解决这个问题:

无限加载渲染所有结果

onAllData 将给出 size 属性中指定的结果数量。通常,设置非常高的大小并不是一个好主意,因为获取和渲染结果会花费更多时间。一个好的替代方法是通过将 pagination 属性设置为 false 并在 size 属性中设置一个值来使用无限滚动,该值告诉组件如何滚动当您到达列表末尾时,需要获取许多结果。

使用滚动 API 获取所有结果

tl;博士Demo

Note

This answer uses reactivesearch for web (for demonstration) but you can use the same props in reactivesearch-native since the API is same.

如果您只对渲染结果感兴趣,则上述方法效果很好。但如果您希望获取当前查询的所有结果,您可以使用 scroll来自 Elasticsearch 的 API。您可以使用 ReactiveList 获取当前查询,然后将其与滚动 API 一起使用。

为此,您可以使用 ReactiveList 上的 onQueryChange 属性:

首先在 ReactiveList 上指定一个 onQueryChange 属性,该属性接收先前和当前查询作为参数:

onQueryChange={(prev, next) => ...}

每次更改查询时都会调用此函数,以便您可以在需要时编写逻辑来获取当前查询的命中(在 next 参数中接收)。

滚动 API 调用返回以下格式的结果:

{
  "_scroll_id": "DnF1ZXJ5VGhlbkZldGNoAgAAAAClGlY4FlotbmJJZXA0U09lMlZFMUNyQ3M2M0EAAAAApRpWORZaLW5iSWVwNFNPZTJWRTFDckNzNjNB",
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 9407,
    "max_score": 1,
    "hits": [
      {
        "_index": "good-books-ds",
        "_type": "good-books-ds",
        "_id": "5676",
        "_score": 1,
        "_source": {
          "authors": "Arthur C. Clarke, Gentry Lee",
          "average_rating": 3.76,
          "average_rating_rounded": 4,
          "books_count": 48,
          "id": 5676,
          "image": "https://images.gr-assets.com/books/1375814957l/112518.jpg",
          "image_medium": "https://images.gr-assets.com/books/1375814957m/112518.jpg",
          "isbn": "1857230213",
          "language_code": "eng",
          "original_publication_year": 1991,
          "original_series": "Rama",
          "original_title": "The Garden of Rama (Rama, #3)",
          "ratings_count": 16389,
          "title": "The Garden of Rama (Rama, #3)"
        }
      },
      {
        "_index": "good-books-ds",
        "_type": "good-books-ds",
        "_id": "5681",
        "_score": 1,
        "_source": {
          "authors": "Darren Shan",
          "average_rating": 4.22,
          "average_rating_rounded": 4,
          "books_count": 52,
          "id": 5681,
          "image": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
          "image_medium": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
          "isbn": "",
          "language_code": "",
          "original_publication_year": 2003,
          "original_series": "Cirque Du Freak",
          "original_title": "Killers of the Dawn (Cirque Du Freak, #9)",
          "ratings_count": 18194,
          "title": "Killers of the Dawn (Cirque Du Freak, #9)"
        }
      },
      {
        "_index": "good-books-ds",
        "_type": "good-books-ds",
        "_id": "5683",
        "_score": 1,
        "_source": {
          "authors": "Laura Joffe Numeroff, Felicia Bond",
          "average_rating": 4.16,
          "average_rating_rounded": 4,
          "books_count": 13,
          "id": 5683,
          "image": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
          "image_medium": "https://s.gr-assets.com/assets/nophoto/book/111x148-bcc042a9c91a29c1d680899eff700a03.png",
          "isbn": "60278684",
          "language_code": "",
          "original_publication_year": 2000,
          "original_series": "",
          "original_title": "If You Take a Mouse to the Movies",
          "ratings_count": 17938,
          "title": "If You Take a Mouse to the Movies"
        }
      },
      {
        "_index": "good-books-ds",
        "_type": "good-books-ds",
        "_id": "5685",
        "_score": 1,
        "_source": {
          "authors": "Orson Scott Card, James Cameron",
          "average_rating": 4.06,
          "average_rating_rounded": 4,
          "books_count": 15,
          "id": 5685,
          "image": "https://images.gr-assets.com/books/1225165505l/40289.jpg",
          "image_medium": "https://images.gr-assets.com/books/1225165505m/40289.jpg",
          "isbn": "99690608",
          "language_code": "eng",
          "original_publication_year": 1989,
          "original_series": "",
          "original_title": "The Abyss",
          "ratings_count": 16318,
          "title": "The Abyss"
        }
      },
      {
        "_index": "good-books-ds",
        "_type": "good-books-ds",
        "_id": "5687",
        "_score": 1,
        "_source": {
          "authors": "Katarina Bivald, Alice Menzies",
          "average_rating": 3.56,
          "average_rating_rounded": 4,
          "books_count": 63,
          "id": 5687,
          "image": "https://images.gr-assets.com/books/1452107441l/25573977.jpg",
          "image_medium": "https://images.gr-assets.com/books/1452107441m/25573977.jpg",
          "isbn": "149262344X",
          "language_code": "eng",
          "original_publication_year": 2013,
          "original_series": "",
          "original_title": "Läsarna i Broken Wheel rekommenderar",
          "ratings_count": 14571,
          "title": "The Readers of Broken Wheel Recommend"
        }
      }
    ]
  }
}

作为 _scroll_id 接收到的值可以传递给滚动 API 以获取下一组结果,依此类推,直到点击次数为零。

Note

If your cluster has a lot of data, its not a good idea to run this logic to fetch all the results every time the query changes. You can add a condition to limit the number of results fetched or store the current query in state and only fetch all the results when required.

下面是一个有关如何使用 ReactiveList 实现此功能的示例。在示例中,每次查询更改时我都会获取结果,但您可以修改它以有条件地获取结果:

在您的渲染函数中:

<ReactiveList
  ...
  size={10}
  onQueryChange={this.handleQueryChange}
/>

这是handleQueryChange函数的样子。这将为您提供当前查询的所有结果:

handleQueryChange = async (prev, next) => {
    // avoid fetching the results for match_all query since dataset is large
    if (next && !next.query.match_all) {
      console.log('Fetching all results for query:', next);

      // modify the query size here if needed (currently it is 10)
      // initial url to obtain scroll id is different

      const initialResults = await this.fetchResults(next, url);

      // keep scrolling till hits are present
      // NOTE: careful if you've a lot of results,
      // in that case you might want to add a condition to limit calls to scroll API

      const scrollResults = await this.fetchScrollResults({
        scroll: "1m",
        scroll_id: initialResults._scroll_id
      });

      // combine the two to get all results
      // concat hits from initialResults with hits from scrollResults

      const allResults = initialResults.hits.hits.concat(scrollResults);
      console.log(`${allResults.length} results found:`, allResults);
    }
};

它首先使用两个函数来获取结果,然后使用 scroll_id 获取结果。两者的端点不同,您可以在 demo 中找到。 。第一个 fetchResults 如下所示:

fetchResults = (query, api) => {
    return fetch(api, {
      method: "POST",
      headers: {
        "content-type": "application/json",
        Authorization: `Basic ${btoa(credentials)}`
      },
      body: JSON.stringify(query)
    })
      .then(res => res.json())
      .catch(err => console.error(err));
};

fetchScrollResults 将使用滚动 API 来获取结果,直到获得的点击次数为 0。

fetchScrollResults = async query => {
    const res = await this.fetchResults(query, scrollUrl);
    const { hits } = res.hits;
    if (hits.length) {
        return [
            ...hits,
            ...(await this.fetchScrollResults({
                scroll: "1m",
                scroll_id: res._scroll_id
            }))
        ];
    }
    return [];
};

检查demo ,结果将显示在控制台中。

关于javascript - 如何获取 ReactiveList 中的所有结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50076655/

相关文章:

javascript - 使用 JS 或 JQuery 的多个条件/禁用选择选项?

javascript - JavaScript 函数中 input type=button 和 input type=submit 之间的差异

javascript - 提供程序 'Task' 必须从 $get 工厂方法返回一个值

javascript - 您如何同时映射生成器结果?

java - 使用java api客户端进行elasticsearch身份验证

elasticsearch - 列表内的ElasticSearch范围

node.js - ReactJS:从 S3 渲染私有(private)图像资源

javascript - Service Worker 注册错误 : Unsupported MIME type ('text/html' )

javascript - ReactJs - 如何将 ApolloProvider 包装在 StatsigProvider 中?

json - 如何在Elasticsearch中查询不同的字段?