Запрос MongoDB: как проверить, содержится ли строка, хранящаяся в документе, в другой строке - PullRequest
1 голос
/ 18 октября 2011

У меня есть коллекция с 8k + строками, и мне нужно проверить, содержится ли определенная строка в другой строке. Например:

StringInDb = "this is a string"
TheOtherString = "this is a long string that contains this is a string"

с linq Я использовал что-то вроде:

from s in DB.Table 
where TheOtherString.IndexOf(s.StringInDb ) > -1
select s.StringInDb;

Как я могу сделать это (эффективно) в mongodb (еще лучше, используя драйвер c # .net)?

Ответы [ 4 ]

4 голосов
/ 18 октября 2011

В mongodb для contains вам нужно использовать регулярное выражение, поэтому запрос c # будет следующим:

var query = Query.Matches("StringParamName", 
     BsonRegularExpression.Create(".*this is a string.*", "-i"));

После того как вы завершили построение запроса, поместите этот запрос в метод Collection.FindAs<DocType>(query).

-i - означает игнорировать регистр

Regexp в mongodb работает медленно, потому что не может использовать index. Но для коллекции 8k это должно работать довольно быстро.

2 голосов
/ 18 октября 2011

Для меня это звучит так, как будто вам нужно использовать map / lower: отобразить все ваши строки из БД и сократить их до тех, которые содержатся в вашей длинной строке. Не могу вспомнить C # с макушки головы. Можете найти его позже, если хотите.

Обновление: родным языком MongoDB является JavaScript, а Map / Reduce запускается "внутри движка mongodb", что подразумевает, что функция map и lower должна быть JavaScript, а не C #. Их можно вызывать из C #, как показано в этом примере, взятом из официальной документации драйвера MogoDB для C # (http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial#CSharpDriverTutorial-MapReducemethod). В этом примере подсчитывается, сколько раз каждый ключ находится в коллекции:

var map =
  "function() {" +
  "    for (var key in this) {" +
  "        emit(key, { count : 1 });" +
  "    }" +
  "}";

var reduce =
  "function(key, emits) {" +
  "    total = 0;" +
  "    for (var i in emits) {" +
  "        total += emits[i].count;" +
  "    }" +
  "    return { count : total };" +
  "}";

var mr = collection.MapReduce(map, reduce);
foreach (var document in mr.GetResults()) {
  Console.WriteLine(document.ToJson());
}
0 голосов
/ 06 мая 2012
"$where" : "\"

Это длинная строка, содержащая эту строку \ ". Match (this.YourFieldName)"

Это ты хочешь?

0 голосов
/ 18 октября 2011

Эта обертка используется в моей производственной системе.Когда вы всегда должны вызывать GetBsonValue (), и он сделает всю остальную работу за вас

/// <summary>
/// Makes a Bson object for current value object
/// </summary>
/// <returns>The Bson object for current value object</returns>
private BsonValue GetBsonValue()
{
    if (!_value.Contains(_wildCard))
        return _value;
    string pattern = ApplyWildCard();
    return BsonRegularExpression.Create(new Regex(pattern, RegexOptions.IgnoreCase));
}

/// <summary>
/// Finds wildcard characters and substitutes them in the value  string
/// </summary>
/// <returns></returns>
private string ApplyWildCard()
{
    return string.Format("^{0}$", _value.Replace(_wildCard, ".*"));
}

Снаружи вы вызываете следующий метод, так что нет никакой возможности забыть:

public QueryComplete BuildQuery()
    {
        return Query.EQ(_key, GetBsonValue());
    }
...