如何在ReactiveList中获取所有结果

时间:2018-04-28 12:42:36

标签: javascript reactjs elasticsearch react-native reactivesearch

我尝试使用所有数据,但它不起作用,因为我只能得到'size'参数中所述的结果数。这是我的部分代码。

<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;
  }
}

2 个答案:

答案 0 :(得分:2)

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

使用无限加载渲染所有结果

onAllData将提供size道具中指定的结果数量。通常,设置一个非常高的size并不是一个好主意,因为它需要更多的时间来获取和渲染结果。一个很好的替代方法是通过将pagination道具设置为false并在size道具中设置值来使用无限滚动,该值告诉组件到达终点时要获取的结果数量列表。

使用滚动API

获取所有结果

tl; dr Demo

  

注意

     

这个答案使用了用于web的反应搜索(用于演示),但是你可以在reactivesearch-native中使用相同的道具,因为API是相同的。

如果您只对呈现结果感兴趣,则上述方法可以正常工作。但是,如果您希望获取当前查询的所有结果,可以使用Elasticsearch的{​​{3}} API。您可以使用ReactiveList获取当前查询,然后将其与滚动API一起使用。

为此,您可以使用onQueryChange上的ReactiveList道具:

首先在onQueryChange上指定一个ReactiveList道具,它接收上一个和当前查询作为参数:

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以获取下一组结果,依此类推,直到命中数为零。

  

注意

     

如果您的群集有大量数据,那么每次查询更改时运行此逻辑以获取所有结果都不是一个好主意。您可以添加条件来限制获取的结果数或将当前查询存储在状态中,并且仅在需要时获取所有结果。

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

render函数中:

<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来获取结果。两者的端点不同,您可以在scroll中找到它们。这是第一个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,结果将显示在控制台中。

答案 1 :(得分:0)

您缺少一个标识唯一组件的键,您还需要将元素包含在函数内部。如果正确调用函数并且数组中有元素,那么这应该可以正常工作。

onAllData(shops) {
 let result = null;
 if (shops !== null) {
   console.log(shops.length);
   result = shops.map((marker,index) => { return (
      <ListItem key={index}>
        <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;
}