【问题标题】:In MongoDB how to search in arrays for sequences and complex searches在 MongoDB 中如何在数组中搜索序列和复杂搜索
【发布时间】:2013-02-08 09:24:37
【问题描述】:

我希望能够按子序列在我的文档中搜索。

例如

{
  "name": "doc1",
  "sequence": ["a", "b", "d", "g", "k"]
}
{
  "name": "doc2",
  "sequence": ["c", "a", "b", "m", "d"]
}

我想按顺序匹配多个项目。查询示例:

  1. 返回所有具有序列 ["a","b"] 的文档。 (返回 doc1 和 doc2)
  2. 返回所有具有“a”且在 3 个位置后为“d”的文档(返回 doc2)
  3. 返回所有具有序列 ["b","d","(whatever)", "k"] 的文档(返回 doc1)

我不确定我可以用 MongoDB 做到这一点。另一种解决方案是将序列保存为字符串而不是数组并使用正则表达式(但我不太喜欢这种解决方案)。

如果我在 MongoDB 中做不到,是否有另一个 noSql 引擎或任何支持这个的引擎?

【问题讨论】:

    标签: mongodb nosql


    【解决方案1】:

    正如另一个答案所说,在 MongoDB 中无法按订单 atm 进行搜索。

    物化路径非常适合寻找序列:http://docs.mongodb.org/manual/tutorial/model-tree-structures/#model-tree-structures-with-materialized-paths 并且可以在这里工作。

    因此,您将拥有第二个字段,其中包含您的序列字段的“路径”:

    {
      "name": "doc2",
      "seq_path": "c,a,b,m,d",
      "sequence": ["c", "a", "b", "m", "d"]
    }
    

    你可以只使用一个预先固定的正则表达式(可以使用索引)来搜索:

    db.col.find({seq_path:/^c,a,b,m,d$/})
    

    或者查找文档以该序列开头的位置:

    db.col.find({seq_path:/^c,a,b/})
    

    这可能是一种方法。

    【讨论】:

      【解决方案2】:

      我认为这在 中是不可能的。

      首先get a particual element不容易,但$elementMatch可以,但据我所知,没有办法获取邻居的值。

      我建议使用字符串。我尝试了一个简短的 示例,效果很好。

      #!/usr/local/bin/perl
      
      use strict;
      use warnings;
      use MongoDB;
      use Data::Dumper;
      
      my $client     = MongoDB::Connection->new(host => 'localhost', port => 27017);
      my $database   = $client->get_database('oho');
      my $documents = $database->get_collection('documents');
      
      $documents->remove();
      
      my $doc1 = {  "name"     => "doc1",
                    "sequence" => ["abdgk"]
                 };
      
      my $doc2 = {
                   "name"      => "doc2",
                   "sequence"  => ["cabmd"]
                 };
      
      $documents->insert($doc1);
      $documents->insert($doc2);
      
      my @case1 = $documents->find( { "sequence" => qr/ab/i } )->all();
      print "case 1:" . Dumper \@case1;
      
      my @case2 = $documents->find( { "sequence" => qr/a..d/i } )->all();
      print "case 2:" . Dumper \@case2;
      
      my @case3 = $documents->find( { "sequence" => qr/bd.*k/i } )->all();
      print "case 3:" . Dumper \@case3;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-30
        • 2021-10-18
        • 2018-11-02
        • 1970-01-01
        • 1970-01-01
        • 2021-01-18
        • 2013-05-28
        • 2016-07-31
        相关资源
        最近更新 更多