提前感谢任何帮助人员!所以,我有两个集合:A
和B
。
A
是个人信息的集合:
{
"_id": "3453hkj54h5k34j5hkjh"
"location": "New York, U.S.",
"first-name": "Archer",
"last-name": "Vice",
"industry": "intelligence"
},
{
"_id": "3453hkj5sdfdddjh",
"location": "London, UK",
"first-name": "Harry",
"last-name": "Potter",
"industry": "security"
},
{
"_id": "345dfdf5sdfdddjh",
"location": "D.C., US",
"first-name": "Obama",
"last-name": "Barack",
"industry": "president"
}
B
是美国境内的位置信息集合:
{
"_id": "998sdfdsfhejf",
"city": "New York",
"zip": "10122",
"state": "NY",
"lat": 40.749,
"longt": -73.9885
},
{
"_id": "998sdfsdfdsfhejf",
"city": "D.C."
"zip": "20500",
"state": "DC",
"lat": 38.8951,
"longt": -77.0369
}
我通过比较A中的位置字段与B中的城市字段来查找居住在美国的人.B应该是A的子字符串,因为A通常包含州或国家信息。
我已经通过以下方式将B转换为数组:
var f = db.collection.find(), n = [];
for (var i = 0; i < f.length(); i++) n.push(f[i]['field']);
现在B是var n=["D.C.", "New York"]
我知道如何检查数组中是否有东西。你这样做:
db.database.find({
field:
{
$in: array
}
});
要检查子字符串,请执行以下操作:
db.database.find({A: /substring/ });
或
db.database.find({A: {$regex: 'substring'}});
预期结果
{
"_id": "3453hkj54h5k34j5hkjh",
"location": "New York, U.S.",
"first-name": "Archer",
"last-name": "Vice",
"industry": "intelligence"
},
{
"_id": "345dfdf5sdfdddjh",
"location": "D.C., US",
"first-name": "Obama",
"last-name": "Barack",
"industry": "President"
}
"D.C., US"
包含子串"D.C."
,它是数组n=["D.C.", "New York"]
中的值。
我知道我可以通过mapreduce来实现它,但它实际上似乎只是一个班轮。我也在学习如何加入这两个系列。
答案 0 :(得分:4)
这在声明中并不是非常简单,但它是可能的。如果您的搜索字词列表与问题中所述的一样短,您可以在一行中将其组合成如下的正则表达式:
db.test.find({location: {$regex: new RegExp(n.join('|'))}})
如果列表不是太长。如果正则表达式过于复杂,那将会很慢。如果它非常短,那么你当然也可以按字面意思写出RegExp。
n
在shell中定义,就像你在问题中一样。我在这里用过:
var n = ["D.C.", "New York"];
这将得到以下结果:
{ "_id" : "3453hkj54h5k34j5hkjh", "location" : "New York, U.S.", "first-name" : "Archer", "last-name" : "Vice", "industry" : "intelligence" }
{ "_id" : "345dfdf5sdfdddjh", "location" : "D.C., US", "first-name" : "Obama", "last-name" : "Barack", "industry" : "president" }
如果您的列表太长,以下是您加入的替代方法:
n.reduce(function (lst, d) {
var res = db.test.find({location: {$regex: d}}).toArray();
Array.prototype.push.apply(lst, res);
return lst;
}, []);
它遍历列表中的所有条目并查找匹配的条目,并将所有结果添加到新列表中。
如果您愿意,可以将它们插入到新的集合中,以避免将其全部保留在内存中。您也可以直接使用搜索,而不是将集合B中的结果提取到列表中。就记忆而言,这也应该更好。
这会将结果保存到集合名称test_result
(在搜索中使用集合A和B):
db.B.find().forEach(function (d) {
db.test_result.insert(db.A.find({location: {$regex: d.city}}).toArray())
});