简体   繁体   English

Mongodb根据字段是否包含数组值作为子字符串来查询集合

[英]Mongodb query a collection based on if the field contains an array value as substring

Thanks in advance for any help guys! 在此先感谢您的帮助! So, I have two collections: A and B . 因此,我有两个集合: AB

A is a collection of personal information: 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 is a collection of location information in united state: 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
}  

I what to find out who lives in US by comparing the location field in A against city field in B. B should be a sub string of A, as A often carries state, or country information. 通过将A中的位置字段与B中的城市字段进行比较来找出谁住在美国。B应该是A的子字符串,因为A经常携带州或国家/地区信息。

I already converted B to an array by: 我已经通过以下方式将B转换为数组:

var f = db.collection.find(), n = [];
for (var i = 0; i < f.length(); i++) n.push(f[i]['field']);

now B is var n=["DC", "New York"] 现在B是var n=["DC", "New York"]

I know how to check if something is in the array. 我知道如何检查数组中是否有东西。 you do: 你做:

db.database.find({
   field: 
      { 
         $in: array 
      } 
   }); 

To check substring you do this: 要检查子字符串,请执行以下操作:

db.database.find({A: /substring/ });

or 要么

db.database.find({A: {$regex: 'substring'}});

expected results are 预期结果是

{
  "_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"
}   

"DC, US" contains substring "DC" which is a value in the array n=["DC", "New York"] . "DC, US"包含子字符串"DC" ,它是数组n=["DC", "New York"]

I know I can do it through mapreduce, but it really just seems to be a one liner. 我知道我可以通过mapreduce做到这一点,但实际上它似乎只是一个班轮。 I'm also learning how to join these two collections. 我也在学习如何加入这两个系列。

This is not super simple to do in a statement, but it is possible. 在语句中做到这一点并不是一件容易的事,但是有可能。 If your list of search terms is as short as you have stated in the question you can do it in one line combining it into a regular expression like this: 如果您的搜索字词列表与问题中所陈述的一样短,则可以将其合并为一个正则表达式,例如一行:

 db.test.find({location: {$regex: new RegExp(n.join('|'))}})

If the list is not too long that is. 如果列表不是太长。 It will be quite slow if the regexp gets too complex. 如果正则表达式变得太复杂,它将非常慢。 If its very short you could ff course then you could also write out the RegExp literally. 如果很短,您可以继续学习,然后也可以逐字写出RegExp。

n is defined in the shell as you have in the question. n是您在问题中定义的外壳程序。 Here i used: 我在这里使用:

var n = ["D.C.", "New York"];

This will give the following result: 这将产生以下结果:

{ "_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" }

EDIT 编辑

Here is an alternative for your join if your list is too long: 如果您的列表过长,这是您加入的替代方法:

n.reduce(function (lst, d) {
    var res = db.test.find({location: {$regex: d}}).toArray();
    Array.prototype.push.apply(lst, res); 
    return lst;
}, []);

It loops over all entries in your list and finds the matching entries and adds up all the results into a new list. 它遍历列表中的所有条目,并找到匹配的条目,并将所有结果加到一个新列表中。

If you want you could insert them into a new collection instead to avoid keeping it all in memory. 如果需要,可以将它们插入新集合中,以避免将其全部保留在内存中。 You could also use a search directly and not extract the result from collection B into a list. 您也可以直接使用搜索,而不是将集合B的结果提取到列表中。 This should also be better in terms of memory. 就内存而言,这也应该更好。

This will save the result to a collection names test_result (using collections A and B in the searches): 这会将结果保存到名称为test_result的集合中(在搜索中使用集合A和B):

db.B.find().forEach(function (d) { 
    db.test_result.insert(db.A.find({location: {$regex: d.city}}).toArray())
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何基于MongoDB中的另一个集合嵌入字段值更新嵌入集合字段的数组? - How to update array of embedded collection field based on another collection embedded field value in MongoDB? 根据数组集合中的值获取 _id 并插入到 mongodb 集合中 - get _id based on value from a collection for a array and insert in mongodb collection 如何根据Mongodb中doc字段中的每个数组项过滤集合 - How to filter a collection based on each array item in a doc field in Mongodb MongoDB 集合中数组的嵌套查询 - Nested Query on Array in MongoDB collection MongoDB 查询集合中的对象数组 - MongoDB query array of objects in collection Laravel - 如何查询数据库中的数组字段是否包含值 - Laravel - How to query if an array field in DB contains a value MONGODB-将集合中的字段添加到Item数组中的字段 - MONGODB - adding a field in collection to a field in Item array MongoDB查询以查找字段中嵌套数组或对象的元素值类型 - Mongodb query to find element value type of nested array or object in a field MongoDB - 选择数组包含文档字段的位置 - MongoDB - Select where array contains a document field 如何根据数组元素向 mongoDB 集合的文档添加新字段 - How to add a new field to mongoDB collection's documents based on an array element
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM