@@ -819,6 +819,56 @@ mod tests {
819
819
Ok ( ( ) )
820
820
}
821
821
822
+ #[ derive( Debug , Serialize , Deserialize , PartialEq ) ]
823
+ struct VideoDocument {
824
+ id : usize ,
825
+ title : String ,
826
+ description : Option < String > ,
827
+ duration : u32 ,
828
+ }
829
+
830
+ async fn setup_test_video_index ( client : & Client , index : & Index ) -> Result < ( ) , Error > {
831
+ let t0 = index
832
+ . add_documents (
833
+ & [
834
+ VideoDocument {
835
+ id : 0 ,
836
+ title : S ( "Spring" ) ,
837
+ description : Some ( S ( "A Blender Open movie" ) ) ,
838
+ duration : 123 ,
839
+ } ,
840
+ VideoDocument {
841
+ id : 1 ,
842
+ title : S ( "Wing It!" ) ,
843
+ description : None ,
844
+ duration : 234 ,
845
+ } ,
846
+ VideoDocument {
847
+ id : 2 ,
848
+ title : S ( "Coffee Run" ) ,
849
+ description : Some ( S ( "Directed by Hjalti Hjalmarsson" ) ) ,
850
+ duration : 345 ,
851
+ } ,
852
+ VideoDocument {
853
+ id : 3 ,
854
+ title : S ( "Harry Potter and the Deathly Hallows" ) ,
855
+ description : None ,
856
+ duration : 7654 ,
857
+ } ,
858
+ ] ,
859
+ None ,
860
+ )
861
+ . await ?;
862
+ let t1 = index. set_filterable_attributes ( [ "duration" ] ) . await ?;
863
+ let t2 = index. set_sortable_attributes ( [ "title" ] ) . await ?;
864
+
865
+ t2. wait_for_completion ( client, None , None ) . await ?;
866
+ t1. wait_for_completion ( client, None , None ) . await ?;
867
+ t0. wait_for_completion ( client, None , None ) . await ?;
868
+
869
+ Ok ( ( ) )
870
+ }
871
+
822
872
#[ meilisearch_test]
823
873
async fn test_multi_search ( client : Client , index : Index ) -> Result < ( ) , Error > {
824
874
setup_test_index ( & client, & index) . await ?;
@@ -841,6 +891,67 @@ mod tests {
841
891
Ok ( ( ) )
842
892
}
843
893
894
+ #[ meilisearch_test]
895
+ async fn test_federated_multi_search (
896
+ client : Client ,
897
+ index_a : Index ,
898
+ index_b : Index ,
899
+ ) -> Result < ( ) , Error > {
900
+ setup_test_index ( & client, & index_a) . await ?;
901
+ setup_test_video_index ( & client, & index_b) . await ?;
902
+
903
+ let query_death_a = SearchQuery :: new ( & index_a) . with_query ( "death" ) . build ( ) ;
904
+ let query_death_b = SearchQuery :: new ( & index_b) . with_query ( "death" ) . build ( ) ;
905
+
906
+ #[ derive( Debug , Serialize , Deserialize , PartialEq ) ]
907
+ #[ serde( untagged) ]
908
+ enum AnyDocument {
909
+ IndexA ( Document ) ,
910
+ IndexB ( VideoDocument ) ,
911
+ }
912
+
913
+ let mut multi_query = client. multi_search ( ) ;
914
+ multi_query. with_search_query ( query_death_a) ;
915
+ multi_query. with_search_query ( query_death_b) ;
916
+ let response = multi_query
917
+ . with_federation ( FederationOptions :: default ( ) )
918
+ . execute :: < AnyDocument > ( )
919
+ . await ?;
920
+
921
+ assert_eq ! ( response. hits. len( ) , 2 ) ;
922
+ dbg ! ( & index_a. uid) ;
923
+ dbg ! ( & index_b. uid) ;
924
+ dbg ! ( & response. hits) ;
925
+ let pos_a = response
926
+ . hits
927
+ . iter ( )
928
+ . position ( |hit| hit. federation . as_ref ( ) . unwrap ( ) . index_uid == index_a. uid )
929
+ . expect ( "No hit of index_a found" ) ;
930
+ let hit_a = & response. hits [ pos_a] ;
931
+ let hit_b = & response. hits [ if pos_a == 0 { 1 } else { 0 } ] ;
932
+ assert_eq ! (
933
+ hit_a. result,
934
+ AnyDocument :: IndexA ( Document {
935
+ id: 9 ,
936
+ kind: "title" . into( ) ,
937
+ number: 90 ,
938
+ value: S ( "Harry Potter and the Deathly Hallows" ) ,
939
+ nested: Nested { child: S ( "tenth" ) } ,
940
+ } )
941
+ ) ;
942
+ assert_eq ! (
943
+ hit_b. result,
944
+ AnyDocument :: IndexB ( VideoDocument {
945
+ id: 3 ,
946
+ title: S ( "Harry Potter and the Deathly Hallows" ) ,
947
+ description: None ,
948
+ duration: 7654 ,
949
+ } )
950
+ ) ;
951
+
952
+ Ok ( ( ) )
953
+ }
954
+
844
955
#[ meilisearch_test]
845
956
async fn test_query_builder ( _client : Client , index : Index ) -> Result < ( ) , Error > {
846
957
let mut query = SearchQuery :: new ( & index) ;
0 commit comments