diff --git a/document.go b/document.go
index 9994363..1fb604d 100644
--- a/document.go
+++ b/document.go
@@ -331,7 +331,8 @@ func (d *Document) Populate(fields ...string) {
 
 				v := reflect.ValueOf(d.self)
 				tt := v.Elem().Type()
-				tmp1 = populate(r, refColl.collection, rawDoc, field, d.self)
+
+				tmp1 = populate(r, d.populatedFields, refColl.collection, rawDoc, field, d.self)
 				nv := reflect.NewAt(tt, v.UnsafePointer())
 				nv.Elem().Set(reflect.ValueOf(tmp1).Elem())
 			}
diff --git a/query.go b/query.go
index 0d6cab5..771da38 100644
--- a/query.go
+++ b/query.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"encoding/json"
 	"errors"
+	"fmt"
 	"github.com/fatih/structtag"
 	"go.mongodb.org/mongo-driver/v2/bson"
 	"go.mongodb.org/mongo-driver/v2/mongo"
@@ -28,7 +29,10 @@ const (
 	OP_FIND       = "find"
 )
 
-func populate(r Reference, rcoll string, rawDoc interface{}, d string, src interface{}) any {
+func populate(r Reference,
+	alreadyPopulated map[string]bool,
+	rcoll string, rawDoc interface{},
+	curDescent string, src interface{}) any {
 	rt := reflect.TypeOf(src)
 	rv := reflect.ValueOf(src)
 	srt := rt
@@ -42,6 +46,27 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 		rv = reflect.New(rt)
 		rv.Elem().Set(reflect.ValueOf(src))
 	}
+	if srt.Kind() == reflect.Struct && !isObject(rawDoc) {
+		nrd := ModelRegistry.Get(srt.Name())
+		if nrd != nil && nrd.collection != rcoll {
+			q, err := nrd.FindByID(rawDoc)
+			if err == nil {
+				rawDoc = q.rawDoc
+				toPopulate := []string{curDescent}
+				if asIDoc, ok := rv.Interface().(IDocument); ok {
+					for k, v := range asIDoc.getPopulated() {
+						if k != curDescent && v {
+							toPopulate = append(toPopulate, k)
+						}
+					}
+				}
+				q.Populate(toPopulate...)
+
+				q.Exec(rv.Interface())
+				src = rv.Interface()
+			}
+		}
+	}
 
 	var fieldsMap [3]string
 	type bsonWhat struct {
@@ -59,12 +84,14 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 	default:
 		w.What = "-"
 	}
+	var fld string
 	var next string
-	if len(strings.Split(d, ".")) > 1 {
-		next = strings.Join(strings.Split(d, ".")[1:], ".")
-		d = strings.Split(d, ".")[0]
+	if len(strings.Split(curDescent, ".")) > 1 {
+		next = strings.Join(strings.Split(curDescent, ".")[1:], ".")
+		fld = strings.Split(curDescent, ".")[0]
 	} else {
-		next = d
+		fld = curDescent
+		next = curDescent
 	}
 	var toReturn interface{}
 	switch w.What {
@@ -76,11 +103,18 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 		} else {
 			rahh = rv
 		}
+		if len(rawDoc.(bson.A)) > 0 {
+			if !isObject(rawDoc.(bson.A)[0]) {
+				next = curDescent
+			}
+		}
+
 		for i, el := range rawDoc.(bson.A) {
 			it := rahh.Index(i)
-			popped := populate(r, rcoll, el, next, it.Interface())
+			rel := el
+			popped := populate(r, alreadyPopulated, rcoll, rel, next, it.Interface())
 			if pidoc, pok := popped.(IDocument); pok {
-				pidoc.setRaw(el)
+				pidoc.setRaw(rel)
 			}
 			poppedVal := reflect.ValueOf(popped)
 			if poppedVal.Kind() == reflect.Pointer {
@@ -110,22 +144,22 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 		var sf reflect.Value
 		var rsf reflect.Value
 		if rv.Kind() == reflect.Pointer {
-			sf = rv.Elem().FieldByName(d)
+			sf = rv.Elem().FieldByName(fld)
 		} else {
-			sf = rv.FieldByName(d)
+			sf = rv.FieldByName(fld)
 		}
 		if rv.Kind() == reflect.Pointer {
-			rsf = rv.Elem().FieldByName(d)
+			rsf = rv.Elem().FieldByName(fld)
 		} else {
-			rsf = rv.FieldByName(d)
+			rsf = rv.FieldByName(fld)
 		}
 
 		var ff reflect.StructField
 		var ok bool
 		if rt.Kind() == reflect.Pointer {
-			ff, ok = rt.Elem().FieldByName(d)
+			ff, ok = rt.Elem().FieldByName(fld)
 		} else {
-			ff, ok = rt.FieldByName(d)
+			ff, ok = rt.FieldByName(fld)
 		}
 
 		if ok {
@@ -137,11 +171,13 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 					if fttt.Kind() == reflect.Pointer || fttt.Kind() == reflect.Slice {
 						fttt = fttt.Elem()
 					}
-					fieldsMap = [3]string{d, fttt.Name(), val.Name}
+					fieldsMap = [3]string{fld, fttt.Name(), val.Name}
 				}
 			}
+		} else {
+			fmt.Println("todo")
 		}
-		intermediate := populate(r, rcoll, dd[fieldsMap[2]], next, sf.Interface())
+		intermediate := populate(r, alreadyPopulated, rcoll, dd[fieldsMap[2]], next, sf.Interface())
 		/*if iidoc, idocOk := intermediate.(IDocument); idocOk {
 			if (reflect.ValueOf(intermediate).CanAddr() && !reflect.ValueOf(intermediate).IsNil()) || !reflect.ValueOf(intermediate).IsZero() {
 				iiid, iok := intermediate.(HasID)
@@ -164,42 +200,44 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 		}
 	default:
 		isNotStructOrSlice = true
-		tto := r.HydratedType
-		if tto.Kind() == reflect.Pointer || tto.Kind() == reflect.Slice {
-			tto = tto.Elem()
-		}
 
-		rawt := ModelRegistry.new_(tto.Name())
-		t := rawt.(IDocument)
-		q := bson.M{"_id": rawDoc}
-		reso := DB.Collection(rcoll).FindOne(context.TODO(), q)
-		if !errors.Is(reso.Err(), mongo.ErrNoDocuments) {
-			var anotherMap = make(bson.M)
-			reso.Decode(&anotherMap)
-			reflect.ValueOf(t).Elem().Set(reflect.ValueOf(rerere(anotherMap, tto, false)).Elem())
-			t.setRaw(anotherMap)
-		}
-		hatred := rv
-		if hatred.Kind() == reflect.Pointer {
-			hatred = hatred.Elem()
-		}
-		if hatred.CanSet() {
-			if reflect.ValueOf(t).Kind() == reflect.Pointer {
-				if hatred.Kind() == reflect.Pointer {
-					hatred.Set(reflect.ValueOf(t))
-				} else {
-					hatred.Set(reflect.ValueOf(t).Elem())
-				}
-				recover()
-			} else {
-				hatred.Set(reflect.ValueOf(t))
+		if r.exists {
+			tto := r.HydratedType
+			if tto.Kind() == reflect.Pointer || tto.Kind() == reflect.Slice {
+				tto = tto.Elem()
 			}
-		} else {
-			src = t
-			toReturn = src
+
+			rawt := ModelRegistry.new_(tto.Name())
+			t := rawt.(IDocument)
+			q := bson.M{"_id": rawDoc}
+			reso := DB.Collection(rcoll).FindOne(context.TODO(), q)
+			if !errors.Is(reso.Err(), mongo.ErrNoDocuments) {
+				var anotherMap = make(bson.M)
+				reso.Decode(&anotherMap)
+				reflect.ValueOf(t).Elem().Set(reflect.ValueOf(rerere(anotherMap, tto, false)).Elem())
+				t.setRaw(anotherMap)
+			}
+			hatred := rv
+			if hatred.Kind() == reflect.Pointer {
+				hatred = hatred.Elem()
+			}
+			if hatred.CanSet() {
+				if reflect.ValueOf(t).Kind() == reflect.Pointer {
+					if hatred.Kind() == reflect.Pointer {
+						hatred.Set(reflect.ValueOf(t))
+					} else {
+						hatred.Set(reflect.ValueOf(t).Elem())
+					}
+				} else {
+					hatred.Set(reflect.ValueOf(t))
+				}
+			} else {
+				src = t
+				toReturn = src
+			}
+			t.SetSelf(t)
+			t.setExists(true)
 		}
-		t.SetSelf(t)
-		t.setExists(true)
 	}
 
 	if toReturn == nil {
@@ -209,6 +247,8 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
 			if !isNotStructOrSlice {
 				sidoc.setRaw(rawDoc)
 			}
+		} else if rv.Kind() == reflect.Pointer && rt.Kind() != reflect.Pointer {
+			rv = rv.Elem()
 		}
 		return rv.Interface()
 	}
@@ -254,50 +294,20 @@ func (q *Query) LoadFile(fields ...string) *Query {
 	return q
 }
 
-func readFields(field string, m *Model) (Reference, string) {
-	var r Reference
-	var keptKey string
+func readFields(field string, m *Model) map[string]Reference {
+	r := make(map[string]Reference)
 	if m == nil {
-		return r, keptKey
+		return r
 	}
-	for k2, v := range m.references {
-		if strings.HasPrefix(k2, field) {
-			r = v
-			keptKey = k2
-			break
-		} else if _, ok := m.references[field]; !ok {
-			splitSegs := strings.Split(field, ".")
-			for ii := 0; ii < len(splitSegs)-1; ii++ {
-				mr, ok2 := m.references[splitSegs[ii]]
-				if ok2 {
-					_, sec, _ := ModelRegistry.HasByName(mr.Model)
-					if sec != nil {
-						refff, ok3 := sec.references[splitSegs[ii+1]]
-						if ok3 {
-							r = refff
-							keptKey = k2
-							break
-						} else {
-							joined := strings.Join(splitSegs[ii+1:], ".")
-							inner1, innerKey := readFields(joined, sec)
-							if inner1.exists {
-								r = inner1
-								keptKey = innerKey
-							}
-							break
-						}
-					}
-				}
-			}
-		} else if ok {
-			r = m.references[field]
-			break
-		}
-		if keptKey != "" {
-			break
+	for k, v := range m.references {
+		if strings.HasPrefix(field, k) {
+			r[k] = v
 		}
 	}
-	return r, keptKey
+	if vv, ok := m.references[field]; ok {
+		r[field] = vv
+	}
+	return r
 }
 
 // Populate populates document references via reflection
diff --git a/util.go b/util.go
index bbef80c..5b5cf57 100644
--- a/util.go
+++ b/util.go
@@ -164,6 +164,14 @@ func incrementInterface(t interface{}) interface{} {
 	return t
 }
 
+func isObject(t interface{}) bool {
+	switch t.(type) {
+	case bson.M, bson.D:
+		return true
+	default:
+		return false
+	}
+}
 func pull(s reflect.Value, idx int, typ reflect.Type) reflect.Value {
 	retI := reflect.New(reflect.SliceOf(typ))
 	for i := 0; i < s.Len(); i++ {