javascript - Mongoose get all documents matching array intersection
问题描述
By array intersection I mean, the inventory has a lot more elements than each document ingredients array, and the result I want to get from the query is all documents which all array elements are contained within the inventory. $all will get me zero results since the inventory has more elements than can be found in ingredients even if all ingredients are found within the inventory,
I have thousands of docs that have an array field of strings
{
...
recipe: "recipe1",
ingredients: [ "1 cup cooked quinoa", "6 tbsp butter", "1 large egg" ]
...
},
{
...
recipe: "recipe2",
ingredients: [ "2 lemons", "2 tbsp butter", "1 large egg" ]
...
}
{
...
recipe: "recipe3",
ingredients: [ "1lb salmon", "1 pinch pepper", "4 spears asparagus" ]
...
}
and I'm trying to find all documents where all elements in the ingredients
array are contained in a sample array that contains lots of elements, lets say for the case this only contains this:
inventory = [ "lemons", "butter", "egg", "milk", "bread", "salmon", "asparagus", "pepper" ]
With this inventory array, I want to get recipe2 and recipe3.
Right now I have this inventory array and query (thanks to turivishal):
let inventory = ["lemons", "butter", "egg", "milk", "bread", "salmon", "asparagus", "pepper"];
inventory = inventory.map((i) => new RegExp(i, "i"));
query:
Recipe.find({
ingredients: { $all: inventory }
})
Expected result:
{
...
recipe: "recipe2",
ingredients: [ "2 lemons", "2 tbsp butter", "1 large egg" ]
...
}
{
...
recipe: "recipe3",
ingredients: [ "1lb salmon", "1 pinch pepper", "4 spears asparagus" ]
...
}
But I'm getting zero results
解决方案
$expr
您可以使用表达式条件在 mquery 中尝试聚合运算符,
- 首先,您可以按
|
顺序符号加入字符串数组并制作一个字符串,并在$regex
搜索中使用它, $filter
迭代循环ingredients
$regexMatch
匹配元素有任何匹配的词$size
获取过滤元素的总大小$eq
匹配过滤结果和实际ingredients
相等
let inventory = ["lemons", "butter", "egg", "milk", "bread", "salmon", "asparagus", "pepper"];
let inventoryStr = inventory.join("|");
// "lemons|butter|egg|milk|bread|salmon|asparagus|pepper"
Recipe.find({
$expr: {
$eq: [
{
$size: {
$filter: {
input: "$ingredients",
cond: {
$regexMatch: {
input: "$$this",
regex: inventoryStr,
options: "i"
}
}
}
}
},
{ $size: "$ingredients" }
]
}
})
推荐阅读
- c++ - C++17 编译器不应该发现对未定义值的传递引用吗?
- c# - ASP.Net MVC 5 - 在控制器外部访问 HttpContext.Current.User 的正确方法?
- solr - 禁用 solr 健康检查的日志
- c++ - 防止向量使类的所有实例相同
- elasticsearch - 如何在不停机的情况下更改弹性搜索集群中现有节点的节点类型(数据、主节点或客户端)?
- google-app-maker - 使用 App Maker 在 Google Docs 中创建表格
- c++ - 找到两个链表的合并点?
- sql - SQL 查询根据特定列值以及插入的降序日期过滤记录
- c# - 在单个按钮中逐行将多个 txtbox 值添加到列数据表?C# SQL
- azure-active-directory - 无法在 AAD 中邀请用户作为访客用户