Как я могу получить все результаты в ReactiveList - PullRequest
0 голосов
/ 28 апреля 2018

Я пытался использовать все данные, но они не работают, так как я могу получить только количество результатов, как указано в параметре '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 голосов
/ 29 апреля 2018

Существует несколько способов решения этой проблемы:

Отображение всех результатов с бесконечной загрузкой

onAllData даст количество результатов, указанное в size проп. Обычно не очень хорошая идея устанавливать очень высокое значение size, так как это займет больше времени для извлечения и рендеринга результатов. Хорошей альтернативой для этого является использование бесконечной прокрутки, установив pagination prop в false и установив значение в size prop, которое сообщает компоненту, сколько результатов нужно извлечь, когда вы достигнете конца списка.

Получение всех результатов с помощью API прокрутки

TL; Dr Демо

Примечание

В этом ответе используется реактивный поиск для веб-сайтов (для демонстрации), но вы можете использовать те же реквизиты в реактивном поиске, поскольку API такой же.

Приведенный выше подход работает нормально, если вы заинтересованы только в рендеринге результатов. Но если вы хотите получить все результаты для текущего запроса, вы можете использовать API scroll от Elasticsearch. Вы можете использовать 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. Конечные точки для обоих отличаются, что вы можете найти в демоверсии 1075 *. Вот как выглядит первый 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 [];
};

Проверьте демо , результаты появятся в консоли.

0 голосов
/ 28 апреля 2018

Вам не хватает ключа, который идентифицирует уникальные компоненты, и вам также нужно обернуть элемент внутри функции. Если функция вызывается правильно и в вашем массиве есть элементы, это должно сработать.

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