是否可以在FirestoreRecyclerOptions中使用Algolia查询?

时间:2018-04-01 09:20:53

标签: android google-cloud-firestore

为了让我的用户能够执行更复杂的搜索,我正在与Algolia合作。

    @foreach($products as $product)
            <div class="col-md-4 col-sm-6">
                 <div class="thumbnail no-border no-padding">
                      <div class="media">
                      <a class="media-link" href="{!! URL::route('products.show', $product->id) !!}">
                      {!! Html::image('images/products/'.$product->image, $product->name) !!}
                      <span class="icon-view">
                      <strong><i class="fa fa-eye"></i></strong>
                      </span>
                      </a>
                     </div>
                     <div class="caption text-center">
                          <h4 class="caption-title">{!! $product->name !!}</h4>

                         <div class="price">
                         <ins>{!! $product->price !!}</ins>
                         {{--<del>$425.00</del>--}}
                         </div>
                         {{ $product->favorite->product_id }}
                      <div class="buttons">
                     @if(count($product->favorite) == 1)
                      <span class="btn btn-theme btn-theme-transparent">
                      <i class="fa fa-heart text-danger"></i>
                     </span>
                     @else
                     {!! Form::open(['route'=>'favorite.store', 'class'=>'favorite-products']) !!}
                     {!! Form::hidden('product_id', $product->id) !!}
                     @if ( Auth::guard( 'web' )->check() != 0 )
                     {!! Form::hidden('user_id', Auth::guard( 'web' )->user()->id) !!}
                     @endif
                     <button class="btn btn-theme btn-theme-transparent btn-wish-list">
                     <i class="fa fa-heart"></i>
                     </button>
                     @endif


                    {!! Form::close() !!}


                  {!! Form::open(['route'=>'add.to.cart', 'class'=>'btn product-shoppingcart-icon']) !!}
                 {!! Form::hidden('pro_id', $product->id) !!}
                 <button class="btn btn-theme btn-theme-transparent btn-icon-left">
                 <i class="fa fa-shopping-cart"></i>{{ trans('interface.addToCart') }}
                 </button>
                {!! Form::close() !!}
                <a class="btn btn-theme btn-theme-transparent btn-compare"
                href="#"><i class="fa fa-exchange"></i></a>
                </div>
              </div>
        </div>
    </div>
@endforeach

我想将此jsonObject转换为与com.algolia.search.saas.Query algolia_query = new com.algolia.search.saas.Query(mLastQuery) .setAttributesToRetrieve("content") .setAttributesToRetrieve("category") .setHitsPerPage(10); index.searchAsync(algolia_query, new CompletionHandler() { @Override public void requestCompleted(JSONObject jsonObject, AlgoliaException e) { Log.d("algolia", jsonObject.toString()); } }); 兼容的内容,以便能够使用FirestoreRecyclerOptions

谢谢!

2 个答案:

答案 0 :(得分:6)

为了更好地理解,我将尝试用一个例子来解释这一点。假设我们有一个FirebaseFirestore对象指向数据库的根引用,而CollectionReference对象指向一个名为products的集合。为此,我们可以使用以下两行代码:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference productsRef = rootRef.collection("products");

我们假设我们有一个Cloud Firestore数据库,如下所示:

Firestore-root
     |
     --- products
            |
            --- productIdOne
            |      |
            |      --- productName: "Milk"
            |
            --- productIdTwo
                   |
                   --- productName: "Soy Milk"
            |
            --- productIdThree
                   |
                   --- productName: "Bacon"

要实现此结构,请使用以下代码将这些产品添加到数据库以及相应的索引中:

Map<String, Object> mapOne = new HashMap<>();
mapOne.put("productName", "Milk");
Map<String, Object> mapTwo = new HashMap<>();
mapTwo.put("productName", "Soy Milk");
Map<String, Object> mapThree = new HashMap<>();
mapThree.put("productName", "Bacon");

WriteBatch writeBatch = rootRef.batch();
writeBatch.set(productsRef.document(), mapOne);
writeBatch.set(productsRef.document(), mapTwo);
writeBatch.set(productsRef.document(), mapThree);
writeBatch.commit();

Client client = new Client(YourApplicationID, YourAPIKey);
Index index = client.getIndex("products");

List<JSONObject> productList = new ArrayList<>();
productList.add(new JSONObject(mapOne));
productList.add(new JSONObject(mapTwo));
productList.add(new JSONObject(mapThree));
index.addObjectsAsync(new JSONArray(productList), null);

我们还假设我们在布局文件中有2个视图,EditTextListView

EditText editText = findViewById(R.id.edit_text);
ListView listView = findViewById(R.id.list_view);

要在ListView中实际显示这些产品,请使用以下代码:

productsRef.get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    List<String> list = new ArrayList<>();
                    for (DocumentSnapshot document : task.getResult()) {
                        list.add(document.getString("productName"));
                    }
                    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list);
                    listView.setAdapter(arrayAdapter);
                } else {
                    Log.d(TAG, "Error getting documents: ", task.getException());
                }
            }
        });

为了根据我们在EditText中输入的文字过滤产品,我们需要添加TextChangedListener,如下所示:

editText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    @Override
    public void afterTextChanged(Editable editable) {
        Query query = new Query(editable.toString())
                .setAttributesToRetrieve("productName")
                .setHitsPerPage(50);
        index.searchAsync(query, new CompletionHandler() {
            @Override
            public void requestCompleted(JSONObject content, AlgoliaException error) {
                try {
                    JSONArray hits = content.getJSONArray("hits");
                    List<String> list = new ArrayList<>();
                    for (int i = 0; i < hits.length(); i++) {
                        JSONObject jsonObject = hits.getJSONObject(i);
                        String productName = jsonObject.getString("productName");
                        list.add(productName);
                    }
                    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list);
                    listView.setAdapter(arrayAdapter);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
});

因此,为了使其工作,我们创建了一个新的适配器对象。这意味着对于我们在EditText中键入的每个字符,我们创建一个新的适配器,并使用来自数据库的结果填充此适配器。要回答您的问题,为了达到您想要的效果,您不必更改JSONObject,您已经创建了一个新的查询对象,应该传递给setQuery()方法在FirestoreRecyclerOptions对象上调用。我刚刚给你一个更简单的例子来理解这个流程。有关详细信息,我还建议您看到 video

答案 1 :(得分:2)

FirebaseUI和Algolia之间没有联系。如果你想显示Algolia的搜索结果,你必须自己构建一个适配器。

您可以考虑使用FirebaseUI's FirebaseIndexedArray获取灵感。但公平警告:它的内部结构和所需的修改都非常复杂。