3

下面是多个查询的“与”操作的工作代码,我可以对查询列表执行“与”操作,对查询列表执行“或”操作。但是在 MongoDB 中有没有一种方法可以动态地对查询列表进行“与”或“或”操作?

public IQueryable<SocialRecord> GetWallSocialRecordsMongoQuery(Dictionary<string, List<string>> languagesPerTerms, string[] sources, DateTime fr, DateTime to)
        {
            try
            {
                var andList = new BindingList<IMongoQuery>
                    {
                        Query.And(Query<SocialRecord>.GTE(record => record.DateCreated, fr),
                                  Query<SocialRecord>.LTE(record => record.DateCreated, to),
                                  Query<SocialRecord>.In(record => record.SocialType, sources))
                    };

                foreach (var languagesPerTerm in languagesPerTerms)
                {
                    var term = languagesPerTerm;
                    andList.Add(Query.Or(Query.And((Query<SocialRecord>.Where(record => record.TermMonitorIds.Contains(term.Key))),
                              Query<SocialRecord>.In(record => record.Language, term.Value))));
                }
                return _collection.FindAs<SocialRecord>(Query.And(andList)).AsQueryable();
            }
            catch (Exception ex)
            {
                Log.Error("Exception in the Method GetWallSocialRecords, in the Class MongoSocialRecordRepository", ex);
            }

            return null;
        }

文件结构

{
    "_id" : ObjectId("53a456b27f781d19f40ac76c"),
    "DateCreated" : ISODate("2014-06-20T15:35:56.000Z"),
    "SocialType" : "facebook",
    "RecordId" : "1474971936_10202431655820767",
    "UserId" : "1474971936",
    "UserProfileUrl" : "********",
    "UserProfilePictureUrl" : "/Downloads/v3/432bfeb8-901e-45a4-b739-1f3f48b69d61/facebook/2014-6/1946689/10492432_10202426005479512_740185019259071925_t.jpg",
    "Description" : "******",
    "MediaHiResUrl" : "",
    "MediaLowResUrl" : "",
    "MediaMedResUrl" : "",
    "SocialCount" : NumberLong(354),
    "SocialCountType" : "likes",
    "Sentiment" : "",
    "SentimentScore" : "0.0000000",
    "IsLocalContent" : true,
    "IsExactMatch" : true,
    "IsHashTag" : false,
    "IsActive" : false,
    "MediaType" : "image",
    "TermMonitorIds" : [ 
        "432bfeb8-901e-45a4-b739-1f3f48b69d61"
    ],
    "UserName" : "***",
    "DisplayName" : "",
    "DirectUrl" : "",
    "IsUk" : true,
    "IsEnglish" : true,
    "Language" : "en",
    "Location" : "GB",
    "DataVersion" : "v3"
}

编辑

我需要得到以下查询:

query {
    "DateCreated" : {
        "$gte" : ISODate("2015-02-02T16:55:37.979Z"),
        "$lte" : ISODate("2015-02-09T16:55:37.979Z")
    },
    "SocialType" : {
        "$in" : ["twitter"]
    },
    "$or" : [{
            "TermMonitorIds" : "b34b8bea-d1e6-4d05-bd25-5d07ad0b691e",
            "Language" : {
                "$in" : ["zh", "eo", "ja"]
            }
        }, {
            "TermMonitorIds" : "c8497f52-70dd-47b6-8abe-afac42c3a009",
            "Language" : {
                "$in" : ["zh", "eo", "ja"]
            }
        }
    ]
}

任何建议将不胜感激。

4

1 回答 1

0

我找到了一种方法,可能对任何人都有帮助:

public IQueryable<SocialRecord> GetWallSocialRecordsMongoQuery(Dictionary<string, List<string>> languagesPerTerms, string[] sources, DateTime fr, DateTime to)
        {
            try
            {
                var list = new BindingList<IMongoQuery>();

                foreach (var languagesPerTerm in languagesPerTerms)
                {
                    var term = languagesPerTerm;
                    list.Add(!term.Value.Contains("All")
                                 ? Query.And(
                                     Query<SocialRecord>.Where(record => record.TermMonitorIds.Contains(term.Key)),
                                     Query<SocialRecord>.In(record => record.Language, term.Value))
                                 : Query<SocialRecord>.Where(record => record.TermMonitorIds.Contains(term.Key)));
                }

                var query = Query.And(Query<SocialRecord>.GTE(record => record.DateCreated, fr),
                              Query<SocialRecord>.LTE(record => record.DateCreated, to),
                              Query<SocialRecord>.In(record => record.SocialType, sources),
                              Query.Or(list));

                //var x = _collection.FindAs<SocialRecord>(query).Explain();

                return _collection.FindAs<SocialRecord>(query).AsQueryable();
            }
            catch (Exception ex)
            {
                Log.Error("Exception in the Method GetWallSocialRecords, in the Class MongoSocialRecordRepository", ex);
            }

            return null;
        }

请注意,带有 $or 运算符的 MongoDB 查询可以在 $or 表达式的每个子句上使用单独的索引。

于 2015-02-09T17:46:27.250 回答