在mongodb中查找数组的最后一个索引

In the back end i m using go lang and for database i use mongoDB. I m trying to find the last document inserted in the embedded array so i can retrieve the document in the last array index without knowing its index.Right now i m getting all the documents of the employee and then find the last index.It is like overloading my RAM as i need to retrieve 1000 of record of employee and store it in ram before finding the last index of the array My struct is as follows

 type (
        Employee struct {
            Name               string
            Password           string
            EmpId              string 
           EmailAddress       string
           Position           string
           Gender             string
           Nationality        string
           Department         string
           MaritalStatus      string
           Approvedby         string
           JoinDate           time.Time
           ConfirmationDate   time.Time
           EndDate            time.Time
            Leave             []*LeaveInfo  
        }
        LeaveInfo struct {
            Total        float64
            Id           int
            Days         float64
            From        time.Time
             To          time.Time  
            Status       string
            Certificate  []*CertificateInfo
        }
        CertificateInfo struct {
            FileName string
            FileType string
            FileSize int

        }

Here is how i do in my application

 My code is follows

    employee := Employee{}
    err = c.Find(bson.M{
                  "empid": "1234"
                 }).One(&result)
    if err != nil {
            log.Fatal(err)
    }
          name:=result.Name        
          lastindex:= result.LeaveInfo[len(result.LeaveInfo)-1].Id

As you can see i retrive the whole employee data and then find the Id of the last document.Is there any better way to do this.Appreciate any help.Please ...Thanks..

Newly Added Codes

 This code is based on your example

   var result bson.M

    query := bson.M{"empid": "1234"}  // gets the employee you are interested in
    match := bson.M{"$match": query}  // Set up the match part of the pipeline
    unwind := bson.M{"$unwind": "$leave"}  // sets up the leave field to be unwound

    pipeline := []bson.M{match, unwind,{
    "$project":bson.M{
           "ID":bson.M{
                "$slice": []interface{}{"$leave.id", -1},
        }
       }


    iter := postCollection.Pipe(pipeline).Iter()
    for iter.Next(&result) {
        fmt.Printf("%+v
", result)
    }
    iter.Close()

This code gives me lot of same document like 542 documents .But all these document are same...

1个回答

If you are running a version on Mongo which has $slice in it, It was introduced in 2.4, you can use it in a Find with the addition of a Select Function, which works like project.

err = c.Find(bson.M{"empid": "1234"}).Select(bson.M{"name": 1, "leave": bson.M{"$slice": -1}}).One(&result) // result is an Employee struct

Otherwise, aggregation is your friend. You need to use a pipeline and unwind the Employee Leave field.

There are a few simple steps:

1) Define a result record based on your Employee record where the Leave field is defined as a single LeaveInfo rather than a slice of LeaveInfos, eg

EmployeeResult struct {
    Name   string    `bson:"name"`
    Leave  LeaveInfo `bson:"leave"`
}

Do not forget to make the bson tag the same name as the LeaveInfo tag in the Employee struct.

2) Then create a pipeline with a couple of stages:

query := bson.M{"empid": "1234"}  // gets the employee you are interested in
match := bson.M{"$match": query}  // Set up the match part of the pipeline
unwind := bson.M{"$unwind": "$leave"}  // sets up the leave field to be unwound
pipeline := []bson.M{match, unwind} // the pipeline you are passing to pipe. I like to split the parts of the pipe call up for clarity and ease of later modification

3) Call Pipe with the pipeline as a parameter then Iter over the results, this should give you one LeaveInfo at a time

var (
    result EmployeeResult
)
iter := postCollection.Pipe(pipeline).Iter()
for iter.Next(&result) {
    fmt.Printf("%+v
", result)
}
iter.Close()

4) At the end of the loop, result will have the last item in the list, or be blank if nothing was read.

drgd73844
drgd73844 感谢您为我指明了正确的方向。我已经研究并找到了此链接stackoverflow.com/questions/37253400/…我已经基于此编写了代码,但结果使我获得了超过数组中记录总数的信息。 更新我的问题,请看一下,请帮助解决此问题。谢谢
3 年多之前 回复
dpbsy60000
dpbsy60000 糟糕,我过早按下回车键。 使用Mongo Shell,您可以运行以下查询:db.c.find({“ empid”:“ 1234”},{“ leave”:{$ slice:-1}})并获取数组中的最后一个条目。 我快速浏览了一下,没有找到使用Go中$ slice的任何示例。
3 年多之前 回复
dqwh2717
dqwh2717 在Mongo 3.2中,您可以将$ slice与Mongo Shell中的负数一起使用,例如
3 年多之前 回复
dtc66318
dtc66318 谢谢user1638680 ..... mongodb中是否还有其他属性可以帮助我们找到最小索引。这绝对比我的代码要好,但是我不希望在ram中为每个内存检索1000条记录 请求,即使我们只检索了离开数组的两个属性。谢谢...再次感谢您的帮助。
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问