【问题标题】:mongoDB - Regex search against partial field valuesmongoDB - 针对部分字段值的正则表达式搜索
【发布时间】:2020-04-09 18:00:48
【问题描述】:

我在国家对象中有国家呼叫代码的国家集合。如何使用电话号码和手机号码查找国家/地区?

const countries = [
  {
    name: 'UAE',
    callingCode: 971
  },
  {
    name: 'USA',
    callingCode: 1
  },
  {
    name: 'UK',
    callingCode: 44
  }
];

const number = '971524500000'; // Input

如何使用 mongoose javascript 中的正则表达式查找给定手机的国家/地区;

【问题讨论】:

  • 为什么要为此使用正则表达式?
  • 因为我认为它比遍历所有国家并使用 String.startWith 或 String.indexOf 检查手机号码是否以 countryCode 之一开头更快
  • @RizwanYaqub :不知道为什么有人要求关闭这个问题,你的 mongoDB 版本是什么? Mongo 中没有直接的功能可以支持它,但是我们可以尝试在 MongoDB v4.2 中做到这一点,直到一些绝种!

标签: javascript regex mongodb mongodb-query aggregation-framework


【解决方案1】:

[https://en.wikipedia.org/wiki/List_of_country_calling_codes][1]

请查看上面有关国家/地区呼叫代码的链接,具体请参阅“树列表”部分。

一种解决方案是基于这棵树在 Mongo 中实现一个模式,以便解码国家代码。

因此,可以创建一个表来存储 Mongo 文档,其中包含字段“1x”“2x”“21x”等(树列表表中的 Y 轴)。

这些文档中的每一个都可以包含从 x=0 到 x=9(树列表表中的 x 轴)的子文档数组。子文档可以包含您要查找的国家/地区名称/代码。您可以在 Mongo 文档中使用对数组的直接索引进行有效查找。

我认为您会发现这是一个非常有效的实现,并且应该涵盖所有基础。

【讨论】:

    【解决方案2】:

    如果您可以将数组重组为一个对象,这将是最快的

    const countries = 
      {
        971: 'UAE', 
        1: 'USA', 
        44: 'UK',
        
      }
    ;
    
    
    var code = 44;
    
    console.log(countries[code]);

    const countries = [
      {
        name: 'UAE',
        callingCode: 971
      },
      {
        name: 'USA',
        callingCode: 1
      },
      {
        name: 'UK',
        callingCode: 44
      }
    ];
    
    
     var myFound =countries.filter(myFunc.bind(this,44));
     
     
    
    function myFunc(code,element) {
    
    
      if(element.callingCode == code){
         
         return element;
      }
    }
    
    console.log(myFound);

    【讨论】:

      【解决方案3】:

      在 MongoDB v 4.2 - 您可以使用 $let$regexFind 来执行此操作:

      db.collection.aggregate([
        {
          $match: {
            $expr: {
              $eq: [
                {
                  $let: {
                    vars: {
                      value: {
                        $regexFind: {
                          input: "971524500000", // pass in as string
                          regex: { $toString: "$callingCode" }
                        }
                      }
                    },
                    in: "$$value.idx",
                  }
                },
                0
              ]
            }
          }
        }
      ]);
      

      测试: MongoDB-Playground

      说明:

      一般用例:

      一般的正则表达式搜索 - 将有一个输入,该输入将是实际字符串的子字符串,Ex.:-

      DB 中的实际字符串: '我们可以在 mongo 中完成'

      输入: mongo(/mongo/ - 会工作)

      您的用例:

      从上述情况,mongo 存在于 db 字段的实际字符串/值中,然后您可以获得该文档,但您的情况不同:

      DB 中的实际字符串: mongo

      输入: '我们可以在 mongo 中完成'

      这样不行,所以使用普通的/We can do it in mongo/ 在这里对你没有帮助(也用正则表达式做一些技巧)。所以我们需要对$regexFind 操作符做一个技巧。与 mongo 文档不同,我们需要将 971524500000 带入 input 字段和正则表达式作为 callingCode 字段的字符串值,反之亦然文档中给出的内容。

      所以一旦我们这样做了,我们会得到如下的结果:

      {
          "match" : "971", /** value of callingCode field */
          "idx" : 0, /** Index of `971` in '971524500000' */
          "captures" : []
      },{
              "match" : "1",
              "idx" : 2,
              "captures" : []
      },
      null /** 3rd doc no match */
      

      由于国家代码必须首先是给定数字,我们需要"idx" : 0 的文档 - 所以我们使用$let 获取返回对象的索引并检查0 并最终使用@987654337 获取相应的文档@。

      注意:

      您需要查看一些内容,以防万一您有以下文档:

        {
          "_id": ObjectId("5e8f67091aa1cc3d2158ade1"),
          "name": "USA",
          "callingCode": 1.0
        },
        {
          "_id": ObjectId("5e8f67091aa1cc3d2158ade3"),
          "name": "somecountry",
          "callingCode": 197.0
        }
      

      & 输入是1971524500000,那么这个查询会将两个文档都带入结果中。这将是您需要检查的情况。无论如何,我建议尝试此查询,而不是将所有文档收集到代码中并提取所需的 o/p,这可能会更好。

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 1970-01-01
        • 2012-01-01
        • 2012-12-11
        • 2011-12-27
        • 1970-01-01
        • 2017-10-30
        • 1970-01-01
        相关资源
        最近更新 更多