查找按最佳匹配排序的所有元素
Find all elements sorted by best matches
我的数据库中有一些名为 "events" 的实体。这些事件中的每一个都包含一个字符串数组,称为 "tags".
我想进行查询以获取与我将在参数中提供的标签数组相匹配的所有事件。
但是,我希望这些事件按如下方式排序:
- 第一个是我在参数中给出的大部分标签。
- 第二个是包含我在参数中给出的大部分标签的第二个。
- 以此类推
如果有多个事件包含相同数量的标签,我希望它们按 "name" 属性 在 [=31] 中排序=]字母顺序.
示例:
- "name" = "event1", "tags" = ["food", "music", "gaming", "sport"]
- "name" = "event2", "tags" = ["gaming"]
- "name" = "event3", "tags" = ["music", "sport"]
- "name" = "event4", "tags" = ["food", "music", "gaming", "sport"]
- "name" = "event5", "tags" = ["music", "sport", "coding"]
- "name" = "event6", "tags" = ["coding"]
- "name" = "event7", "tags" = ["food", "gaming", "sport"]
我在这个例子的参数中给出的标签数组是:["food"、"music"、"gaming"、"sport"]
此示例的结果将是一个事件数组,按顺序包含:
事件 1、事件 4、事件 7、事件 3、事件 5、事件 2
要获取包含标签的所有事件,我只需使用 "$or" 运算符进行查询。如果事件至少包含参数中给定的标签之一,这使我能够获取所有事件。
代码:
var events []model.Event
var MyQuery []map[string]interface{}
for i := 0; i < len(tags); i++ {
currentCondition := bson.M{"tags": tags[i]}
MyQuery = append(MyQuery, currentCondition)
}
err := dbEvents.C(collectionEvents).Find(bson.M{"$or": OrQuery}).All(&events)
但我真的不知道如何像我给你展示的那样对它们进行排序。
package main
import (
"fmt"
"github.com/ahmetb/go-linq"
)
type T struct {
Name string
Tags []string
}
func main() {
params := []string{"food", "music", "gaming", "sport"}
t := []T{
T{Name: "event1", Tags: []string{"food", "music", "gaming", "sport"}},
T{Name: "event2", Tags: []string{"gaming"}},
T{Name: "event3", Tags: []string{"music", "sport"}},
T{Name: "event4", Tags: []string{"food", "music", "gaming", "sport"}},
T{Name: "event5", Tags: []string{"music", "coding", "sport"}},
T{Name: "event6", Tags: []string{"coding"}},
T{Name: "event7", Tags: []string{"food", "gaming", "sport"}},
}
var result []T
linq.From(t).SortT(func(t1 T, t2 T) bool {
var rs1 []string
linq.From(t1.Tags).IntersectByT(linq.From(params), func(str string) string {
return str
}).ToSlice(&rs1)
var rs2 []string
linq.From(t2.Tags).IntersectByT(linq.From(params), func(str string) string {
return str
}).ToSlice(&rs2)
return len(rs1) > len(rs2)
}).ToSlice(&result)
fmt.Printf("%+v", result)
}
[{Name:event1 Tags:[food music gaming sport]} {Name:event4 Tags:[food music gaming sport]} {Name:event7 Tags:[food gaming sport]} {Name:event3 Tags:[music sport]} {Name:event5 Tags:[music coding sport]} {Name:event2 Tags:[gaming]} {Name:event6 Tags:[coding]}]
以上程序根据您的要求对数组进行排序,希望对您有所帮助。
我的数据库中有一些名为 "events" 的实体。这些事件中的每一个都包含一个字符串数组,称为 "tags".
我想进行查询以获取与我将在参数中提供的标签数组相匹配的所有事件。
但是,我希望这些事件按如下方式排序:
- 第一个是我在参数中给出的大部分标签。
- 第二个是包含我在参数中给出的大部分标签的第二个。
- 以此类推
如果有多个事件包含相同数量的标签,我希望它们按 "name" 属性 在 [=31] 中排序=]字母顺序.
示例:
- "name" = "event1", "tags" = ["food", "music", "gaming", "sport"]
- "name" = "event2", "tags" = ["gaming"]
- "name" = "event3", "tags" = ["music", "sport"]
- "name" = "event4", "tags" = ["food", "music", "gaming", "sport"]
- "name" = "event5", "tags" = ["music", "sport", "coding"]
- "name" = "event6", "tags" = ["coding"]
- "name" = "event7", "tags" = ["food", "gaming", "sport"]
我在这个例子的参数中给出的标签数组是:["food"、"music"、"gaming"、"sport"]
此示例的结果将是一个事件数组,按顺序包含: 事件 1、事件 4、事件 7、事件 3、事件 5、事件 2
要获取包含标签的所有事件,我只需使用 "$or" 运算符进行查询。如果事件至少包含参数中给定的标签之一,这使我能够获取所有事件。
代码:
var events []model.Event
var MyQuery []map[string]interface{}
for i := 0; i < len(tags); i++ {
currentCondition := bson.M{"tags": tags[i]}
MyQuery = append(MyQuery, currentCondition)
}
err := dbEvents.C(collectionEvents).Find(bson.M{"$or": OrQuery}).All(&events)
但我真的不知道如何像我给你展示的那样对它们进行排序。
package main
import (
"fmt"
"github.com/ahmetb/go-linq"
)
type T struct {
Name string
Tags []string
}
func main() {
params := []string{"food", "music", "gaming", "sport"}
t := []T{
T{Name: "event1", Tags: []string{"food", "music", "gaming", "sport"}},
T{Name: "event2", Tags: []string{"gaming"}},
T{Name: "event3", Tags: []string{"music", "sport"}},
T{Name: "event4", Tags: []string{"food", "music", "gaming", "sport"}},
T{Name: "event5", Tags: []string{"music", "coding", "sport"}},
T{Name: "event6", Tags: []string{"coding"}},
T{Name: "event7", Tags: []string{"food", "gaming", "sport"}},
}
var result []T
linq.From(t).SortT(func(t1 T, t2 T) bool {
var rs1 []string
linq.From(t1.Tags).IntersectByT(linq.From(params), func(str string) string {
return str
}).ToSlice(&rs1)
var rs2 []string
linq.From(t2.Tags).IntersectByT(linq.From(params), func(str string) string {
return str
}).ToSlice(&rs2)
return len(rs1) > len(rs2)
}).ToSlice(&result)
fmt.Printf("%+v", result)
}
[{Name:event1 Tags:[food music gaming sport]} {Name:event4 Tags:[food music gaming sport]} {Name:event7 Tags:[food gaming sport]} {Name:event3 Tags:[music sport]} {Name:event5 Tags:[music coding sport]} {Name:event2 Tags:[gaming]} {Name:event6 Tags:[coding]}]
以上程序根据您的要求对数组进行排序,希望对您有所帮助。