如何查找与查询中具有完全相同数组条目的文档
How to find documents with exactly the same array entries as in a query
我在 collection 中有文档,看起来像这样:
[
{
userId: 1,
itemsIds: [399957190, 366369952],
hash: '85e765840b1cd3c413404cdf6b8fb2a4'
},
{
userId: 2,
itemsIds: [349551151, 366369952],
hash: 'a28fa334515749b1b13fcd2183edb8de'
},
{
userId: 3,
itemsIds: [399957190, 366369952],
hash: '85e765840b1cd3c413404cdf6b8fb2a4'
}
]
这些用户在他们的列表中有最喜欢的项目。我想要一个用户的列表给其他人,看看他们是否相等。如果是,我想在我的代码中将它们标记为一对并执行一些操作。
在上面的示例中,用户 1 和 3 具有相同的收藏夹列表。
如何使用包含我列出的值的数组来查找用户?
这里有几个 "very useful cases" 实际上试图在数组内容上创建 "unique hash" 实际上是 "getting in the way" 可以轻松解决的无数问题。
寻找 "Me"
的共同点
例如,如果您从所提供的示例中获取 "user 1",并考虑到您已经加载了该数据,并且希望通过匹配的 "itemsIds" 从当前的内容中找到 "those in common with me" user对象有,那么有两种简单的查询方式:
找到"exactly"相同的:是你要检查其他用户数据的地方,看看那些有相同[=90=的用户】 利益。 $all
查询运算符的 "unordered" 用法很简单:
db.collection.find({
"itemsIds": { "$all": [399957190, 366369952] },
"userId": { "$ne": 1 }
})
return"user 3",因为它们是 "both" 常见的 "itemsIds" 条目。顺序在这里并不重要,因为它总是以任何顺序匹配,只要它们都在那里。这是 $and
作为查询参数的另一种形式。
找到我的共同点 "similar"": 这基本上是在问 "do you have something that is the same?"。为此,您可以使用 $in
查询运算符。如果满足指定条件的 "either",它将匹配:
db.collection.find({
"itemsIds": { "$in": [399957190, 366369952] },
"userId": { "$ne": 1 }
})
在这种情况下 "both" "user 2" 和 "user 3" 将匹配,因为它们 "at least" 共享 "one" 指定的条件,这意味着"something in common" 包含查询的源数据。
这实际上是$or
查询运算符的另一种形式,和以前一样,在给定要应用的条件下,这样写会更简单和简洁。
寻找共同点"Things"
在某些情况下,您可能希望在没有基础 "user" 的情况下找到东西 "in common"。那么,您如何判断 "user 1" 和 "user 2" 共享相同的 "itemIds",或者事实上,不同的用户可能单独共享相同的 "itemIds" 值,但他们是谁?
获得完全匹配: 当然是您查看 "itemsIds" 值和 $group
值的地方。一般来说 "order is important" 在这里,所以最好你有它们 "pre-ordered" 并且始终如一地使它变得如此简单:
db.collection.aggregate([
{ "$group": {
"_id": "$itemsIds",
"common": { "$push": "$userId" }
}}
])
这就是它真正的全部,只要订单已经存在。如果没有,那么你可以做一个稍微长一点的缠绕形式来做 "ordering",但同样可以说生成 "hash":
db.collection.aggregate([
{ "$unwind": "$itemsIds" },
{ "$sort": { "_id": 1, "itemsIds": 1 } },
{ "$group": {
"_id": "$_id",
"userId": { "$first": "$userId" },
"itemsIds": { "$push": "$itemsIds" }
}},
{ "$group": {
"_id": "$itemsIds",
"common": { "$push": "$userId" }
}}
])
性能不"super",但它说明了为什么在添加数组条目时始终保持有序。这是一个非常简单的过程。
Common "user" 到 "items": 这是另一个简单的过程,上面用 "breaking down" 下面的数组抽象$unwind
,然后基本上分组回来:
db.collection.aggregate([
{ "$unwind": "$itemsIds" },
{ "$group": {
"_id": "$itemsIds",
"users": { "$addToSet": "$userId" }
}}
])
再一次,只是 $addToSet
的一个简单分组聚合器就可以完成这项工作,并为每个 "itemsIds" 值收集 "distinct userId" 值。
这些都是基本的解决方案,我可以继续 "set intersections" 什么不行,但这是 "primer".
不要尝试计算 "hash",MongoDB 有一个很好的 "arsenal" 来匹配条目。使用它和 "abuse it" 一样,直到它坏掉。那就更努力吧
我在 collection 中有文档,看起来像这样:
[
{
userId: 1,
itemsIds: [399957190, 366369952],
hash: '85e765840b1cd3c413404cdf6b8fb2a4'
},
{
userId: 2,
itemsIds: [349551151, 366369952],
hash: 'a28fa334515749b1b13fcd2183edb8de'
},
{
userId: 3,
itemsIds: [399957190, 366369952],
hash: '85e765840b1cd3c413404cdf6b8fb2a4'
}
]
这些用户在他们的列表中有最喜欢的项目。我想要一个用户的列表给其他人,看看他们是否相等。如果是,我想在我的代码中将它们标记为一对并执行一些操作。
在上面的示例中,用户 1 和 3 具有相同的收藏夹列表。 如何使用包含我列出的值的数组来查找用户?
这里有几个 "very useful cases" 实际上试图在数组内容上创建 "unique hash" 实际上是 "getting in the way" 可以轻松解决的无数问题。
寻找 "Me"
的共同点例如,如果您从所提供的示例中获取 "user 1",并考虑到您已经加载了该数据,并且希望通过匹配的 "itemsIds" 从当前的内容中找到 "those in common with me" user对象有,那么有两种简单的查询方式:
找到"exactly"相同的:是你要检查其他用户数据的地方,看看那些有相同[=90=的用户】 利益。
$all
查询运算符的 "unordered" 用法很简单:db.collection.find({ "itemsIds": { "$all": [399957190, 366369952] }, "userId": { "$ne": 1 } })
return"user 3",因为它们是 "both" 常见的 "itemsIds" 条目。顺序在这里并不重要,因为它总是以任何顺序匹配,只要它们都在那里。这是
$and
作为查询参数的另一种形式。找到我的共同点 "similar"": 这基本上是在问 "do you have something that is the same?"。为此,您可以使用
$in
查询运算符。如果满足指定条件的 "either",它将匹配:db.collection.find({ "itemsIds": { "$in": [399957190, 366369952] }, "userId": { "$ne": 1 } })
在这种情况下 "both" "user 2" 和 "user 3" 将匹配,因为它们 "at least" 共享 "one" 指定的条件,这意味着"something in common" 包含查询的源数据。
这实际上是
$or
查询运算符的另一种形式,和以前一样,在给定要应用的条件下,这样写会更简单和简洁。
寻找共同点"Things"
在某些情况下,您可能希望在没有基础 "user" 的情况下找到东西 "in common"。那么,您如何判断 "user 1" 和 "user 2" 共享相同的 "itemIds",或者事实上,不同的用户可能单独共享相同的 "itemIds" 值,但他们是谁?
获得完全匹配: 当然是您查看 "itemsIds" 值和
$group
值的地方。一般来说 "order is important" 在这里,所以最好你有它们 "pre-ordered" 并且始终如一地使它变得如此简单:db.collection.aggregate([ { "$group": { "_id": "$itemsIds", "common": { "$push": "$userId" } }} ])
这就是它真正的全部,只要订单已经存在。如果没有,那么你可以做一个稍微长一点的缠绕形式来做 "ordering",但同样可以说生成 "hash":
db.collection.aggregate([ { "$unwind": "$itemsIds" }, { "$sort": { "_id": 1, "itemsIds": 1 } }, { "$group": { "_id": "$_id", "userId": { "$first": "$userId" }, "itemsIds": { "$push": "$itemsIds" } }}, { "$group": { "_id": "$itemsIds", "common": { "$push": "$userId" } }} ])
性能不"super",但它说明了为什么在添加数组条目时始终保持有序。这是一个非常简单的过程。
Common "user" 到 "items": 这是另一个简单的过程,上面用 "breaking down" 下面的数组抽象
$unwind
,然后基本上分组回来:db.collection.aggregate([ { "$unwind": "$itemsIds" }, { "$group": { "_id": "$itemsIds", "users": { "$addToSet": "$userId" } }} ])
再一次,只是
$addToSet
的一个简单分组聚合器就可以完成这项工作,并为每个 "itemsIds" 值收集 "distinct userId" 值。
这些都是基本的解决方案,我可以继续 "set intersections" 什么不行,但这是 "primer".
不要尝试计算 "hash",MongoDB 有一个很好的 "arsenal" 来匹配条目。使用它和 "abuse it" 一样,直到它坏掉。那就更努力吧