@@ -15,7 +15,7 @@ use self::words::Words;
15
15
use super :: query_tree:: { Operation , PrimitiveQueryPart , Query , QueryKind } ;
16
16
use crate :: search:: criteria:: geo:: Geo ;
17
17
use crate :: search:: { word_derivations, WordDerivationsCache } ;
18
- use crate :: { AscDesc as AscDescName , DocumentId , FieldId , Index , Member , Result } ;
18
+ use crate :: { AscDesc as AscDescName , DocumentId , Error , FieldId , Index , Member , Result } ;
19
19
20
20
mod asc_desc;
21
21
mod attribute;
@@ -318,33 +318,22 @@ pub fn resolve_query_tree(
318
318
}
319
319
320
320
pub fn resolve_phrase ( ctx : & dyn Context , phrase : & [ String ] ) -> Result < RoaringBitmap > {
321
- let mut candidates = RoaringBitmap :: new ( ) ;
322
321
let winsize = phrase. len ( ) . min ( 7 ) ;
323
322
324
- for win in phrase. windows ( winsize) {
325
- // Get all the documents with the matching distance for each word pairs.
326
- let mut bitmaps = Vec :: with_capacity ( winsize. pow ( 2 ) ) ;
327
- for ( offset, s1) in win. iter ( ) . enumerate ( ) {
328
- for ( dist, s2) in win. iter ( ) . skip ( offset + 1 ) . enumerate ( ) {
329
- match ctx. word_pair_proximity_docids ( s1, s2, dist as u8 + 1 ) ? {
330
- Some ( m) => bitmaps. push ( m) ,
331
- // If there are no document for this distance, there will be no
332
- // results for the phrase query.
333
- None => return Ok ( RoaringBitmap :: new ( ) ) ,
334
- }
335
- }
336
- }
337
-
338
- // We sort the bitmaps so that we perform the small intersections first, which is faster.
339
- bitmaps. sort_unstable_by ( |a, b| a. len ( ) . cmp ( & b. len ( ) ) ) ;
340
- candidates &= bitmaps. and ( ) ;
341
-
342
- // There will be no match, return early
343
- if candidates. is_empty ( ) {
344
- break ;
345
- }
346
- }
347
- Ok ( candidates)
323
+ phrase
324
+ . windows ( winsize)
325
+ . flat_map ( |win| {
326
+ win. iter ( ) . enumerate ( ) . flat_map ( move |( offset, s1) | {
327
+ win. iter ( ) . skip ( offset + 1 ) . enumerate ( ) . map ( move |( dist, s2) | {
328
+ ctx. word_pair_proximity_docids ( s1, s2, dist as u8 + 1 )
329
+ // If there are no document for this distance, there will be no
330
+ // results for the phrase query.
331
+ . map ( |m| m. unwrap_or_default ( ) )
332
+ } )
333
+ } )
334
+ } )
335
+ . and ( )
336
+ . map_err ( Error :: from)
348
337
}
349
338
350
339
fn all_word_pair_proximity_docids < T : AsRef < str > , U : AsRef < str > > (
0 commit comments