| 206 | } |
| 207 | |
| 208 | func (sr *SearchRequest) decorateQuery(indexName string, q query.Query, |
| 209 | cache *collMetaFieldCache) (query.Query, query.Query) { |
| 210 | var docIDQuery *query.DocIDQuery |
| 211 | var ok bool |
| 212 | // bail out early if the query is not a docID one and there are |
| 213 | // no target collections requested in search request. |
| 214 | if docIDQuery, ok = q.(*query.DocIDQuery); !ok && len(sr.Collections) == 0 { |
| 215 | return nil, q |
| 216 | } |
| 217 | if cache == nil { |
| 218 | cache = metaFieldValCache |
| 219 | } |
| 220 | // bail out early if the index is a single collection index as there |
| 221 | // won't be any docID decorations done during indexing as well as the |
| 222 | // collection scoping during the querying also redundant. |
| 223 | var sdm *sourceDetails |
| 224 | if sdm, ok = cache.getSourceDetailsMap(indexName); !ok || |
| 225 | len(sdm.collUIDNameMap) <= 1 { |
| 226 | return nil, q |
| 227 | } |
| 228 | |
| 229 | // if this is a multi collection index and the query is for docID, |
| 230 | // then decorate the target docIDs with cuid prefixes. |
| 231 | if docIDQuery != nil { |
| 232 | decoratedQuery := *docIDQuery |
| 233 | |
| 234 | hash := make(map[string]struct{}) |
| 235 | for _, cname := range sr.Collections { |
| 236 | hash[cname] = struct{}{} |
| 237 | } |
| 238 | newIDs := make([]string, 0, len(decoratedQuery.IDs)) |
| 239 | for cuid, cname := range sdm.collUIDNameMap { |
| 240 | if _, ok := hash[cname]; !ok && len(hash) > 0 { |
| 241 | continue |
| 242 | } |
| 243 | cBytes := make([]byte, 4) |
| 244 | binary.LittleEndian.PutUint32(cBytes, cuid) |
| 245 | for _, docID := range decoratedQuery.IDs { |
| 246 | newIDs = append(newIDs, string(append(cBytes, |
| 247 | []byte(docID)...))) |
| 248 | } |
| 249 | } |
| 250 | decoratedQuery.IDs = newIDs |
| 251 | return q, &decoratedQuery |
| 252 | } |
| 253 | |
| 254 | // if the search is scoped to specific collections then add |
| 255 | // collection specific conjunctions with multi collection indexes. |
| 256 | cjnq := query.NewConjunctionQuery([]query.Query{q}) |
| 257 | djnq := query.NewDisjunctionQuery(nil) |
| 258 | |
| 259 | for _, col := range sr.Collections { |
| 260 | queryStr := cache.getMetaFieldValue(indexName, col) |
| 261 | mq := query.NewMatchQuery(queryStr) |
| 262 | mq.Analyzer = "keyword" |
| 263 | mq.SetField(CollMetaFieldName) |
| 264 | djnq.AddQuery(mq) |
| 265 | } |