我正在尝试确定要获取MongoDB集合中所需数据的.filter或.some的哪种组合。
首先,我有一个docs数组,如下所示:
let docs = [
{ _id: '5ba39a12179b771820413ad8',
branches:
[ { _id: '3nc26645121f0613be08167r', name: 'New York' },
{ _id: '3fc26645121f0613be08185d', name: 'Los Angeles' },
{ _id: '2hc26648121f0613be081862', name: 'Seattle' },
{ _id: '7jc2664a121f0613be081869', name: 'Chicago' },
{ _id: '7ju2664a121f0613be08186e', name: 'Charlotte' } ],
updatedAt: '2018-09-20T13:01:06.709Z',
createdAt: '2018-09-20T13:01:06.709Z' },
{ _id: '3ya39a12179b771820413af5',
branches:
[ { _id: '3nc26645121f0613be08167r', name: 'New York' },
{ _id: '5ac26645121f0613be08145d', name: 'Miami' },
{ _id: '5ac2664a121f0613be08154s', name: 'Sacramento' } ],
updatedAt: '2018-09-20T13:01:06.709Z',
createdAt: '2018-09-20T13:01:06.709Z'
},
{ _id: '2sa39a12179b771820413gy4',
branches:
[ { _id: '1rd26645121d5613be08167h', name: 'Denver' },
{ _id: '5ac2664a121f0613be08154s', name: 'Sacramento' } ],
updatedAt: '2018-09-20T13:01:06.709Z',
createdAt: '2018-09-20T13:01:06.709Z'
}
];
我有一个传入的用户值数组,它们是ID,看起来像这样:
let filterValues = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"];
现在我要编写的查询将返回一个新的docs
数组,该数组仅包含filterValues
数组中的ID与{内的ID之间具有匹配项的文档每个文档根目录上的{1}}属性(它是一个数组)。
在我在此处提供的示例中,结果数组应包含原始branches
数组的3个文档中的2个-具体来说,前两个文档是因为它们都包含至少一个ID在各自的docs
数组中传递-从我的文档数据分配给Charlotte和Miami的ID。
有没有一种方法可以使用branches
,.filter
或.includes
或某种组合来编写?
为清楚起见,最终的过滤结果应如下所示:
.some
答案 0 :(得分:3)
const result = array.filter(({ branches }) => branches.some(({ _id }) => filterValues.includes(_id)))
如果您只是按照自己的想法去做,那该怎么办。
答案 1 :(得分:1)
奇怪的是,由于您已经提出了应该使用的工具,因此您自己还没有实现这一点……差不多了。
首先,您需要根据条件获取docs
的子集,以及为此目的设计的.filter
,因此
var filteredDocs = docs.filter(doc =>
// here we need an expression of whether the doc.branches contains an id from filterValues
)
接下来,您必须确定.branches
的{{1}}中是否有doc
的ID,filterValues
是一个数组,所以.branches
在这里合适:
.some
最后,您需要检查var filteredDocs = docs.filter(doc =>
doc.branches.some(branch =>
// here an expression should check whether branch._id is among filterValues
)
)
是否在branch._id
中,最简单的方法是使用filterValues
(也可以使用.includes
,但是因为id是唯一的,所以没有意义。
.some
您可以将它用作单行代码,这有点难以理解:
var filteredDocs = docs.filter(doc =>
doc.branches.some(branch =>
filterValues.includes(branch._id)
)
)
在控制台中尝试此操作将向您显示结果(请注意,var filteredDocs = docs.filter(doc => doc.branches.some(branch => filterValues.includes(branch._id)))
的发布语法中不正确):
docs
答案 2 :(得分:1)
以下是您要执行的操作的可行示例:
const data = [{ _id: "5ba39a12179b771820413ad8", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "3fc26645121f0613be08185d", name: 'Los Angeles' }, { _id: "2hc26648121f0613be081862", name: 'Seattle' }, { _id: "7jc2664a121f0613be081869", name: 'Chicago' }, { _id: "7ju2664a121f0613be08186e", name: 'Charlotte' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }, { _id: "3ya39a12179b771820413af5", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "5ac26645121f0613be08145d", name: 'Miami' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " }, { _id: "2sa39a12179b771820413gy4", branches: [{ _id: "1rd26645121d5613be08167h", name: 'Denver' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " } ]
const vals = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"]
const result = data.filter(x => x.branches.some(y => vals.includes(y._id)))
console.log(result)
这是简短的ES6版本,主要在此处使用箭头功能等来简化内容。扩展为:
const data = [{ _id: "5ba39a12179b771820413ad8", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "3fc26645121f0613be08185d", name: 'Los Angeles' }, { _id: "2hc26648121f0613be081862", name: 'Seattle' }, { _id: "7jc2664a121f0613be081869", name: 'Chicago' }, { _id: "7ju2664a121f0613be08186e", name: 'Charlotte' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }, { _id: "3ya39a12179b771820413af5", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "5ac26645121f0613be08145d", name: 'Miami' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " }, { _id: "2sa39a12179b771820413gy4", branches: [{ _id: "1rd26645121d5613be08167h", name: 'Denver' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " } ]
const vals = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"]
const result = data.filter(function(obj) {
return obj.branches.some(function(branch) {
return vals.includes(branch._id)
})
})
console.log(result)
基本上,您首先要filter
主数组(通过Array.filter
),在内部使用Array.some
,它会检查是否包含任何branches
_id (通过Array.include
)在filter
数组中。就这么简单。
答案 3 :(得分:1)
let docs = [{ _id: "5ba39a12179b771820413ad8", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "3fc26645121f0613be08185d", name: 'Los Angeles' }, { _id: "2hc26648121f0613be081862", name: 'Seattle' }, { _id: "7jc2664a121f0613be081869", name: 'Chicago' }, { _id: "7ju2664a121f0613be08186e", name: 'Charlotte' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z" }, { _id: "3ya39a12179b771820413af5", branches: [{ _id: "3nc26645121f0613be08167r", name: 'New York' }, { _id: "5ac26645121f0613be08145d", name: 'Miami' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " }, { _id: "2sa39a12179b771820413gy4", branches: [{ _id: "1rd26645121d5613be08167h", name: 'Denver' }, { _id: "5ac2664a121f0613be08154s", name: 'Sacramento' } ], updatedAt: "2018-09-20T13:01:06.709Z", createdAt: "2018-09-20T13:01:06.709Z " } ]
let filterValues = ["5ac26645121f0613be08145d", "7ju2664a121f0613be08186e"]
let result = [];
// For every items in docs
_.each(docs, item => {
// Filter an item with filter values
filterValues.forEach (value => {
if (_.findWhere(item.branches, {_id: value})) {
// Check and store it in the array
result.push(item);
}
});
});
console.log(result);
<script src="https://fastcdn.org/Underscore.js/1.8.3/underscore-min.js"></script>