在MongoDB中如何在数组中搜索序列和复杂搜索

时间:2013-02-08 09:24:37

标签: mongodb nosql

我希望能够通过子序列搜索我的文档。

例如

{
  "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”,“(what)”,“k”]的文档(返回doc1)
  4. 我不确定我能用MongoDB做到这一点。另一种解决方案是将序列保存为字符串而不是数组并使用正则表达式(但我不太喜欢那种解决方案)。

    如果我不能在MongoDB中执行此操作,是否有另一个noSql引擎或支持此功能的引擎?

2 个答案:

答案 0 :(得分: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/})

这可能是一种方式。

答案 1 :(得分:0)

我认为无法做到这一点。

首先,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;