Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database Amazon SimpleDB查询以查找;“朋友发帖”;_Database_Amazon Simpledb - Fatal编程技术网

Database Amazon SimpleDB查询以查找;“朋友发帖”;

Database Amazon SimpleDB查询以查找;“朋友发帖”;,database,amazon-simpledb,Database,Amazon Simpledb,我一直在开发一个iPhone应用程序,它可以查询一个服务器,转发我在Amazon SimpleDB中存储的数据。我有一个由不同用户提交的数据库表。我正在与Facebook交互以检索Facebook好友,并希望查询“提交”以查找好友的帖子,如: SELECT * FROM submissions WHERE userID = '00123' OR userID = '00124' OR .... (通过完整的朋友列表) 我认为这种select语句会导致Amazon查询受限- [每个Select

我一直在开发一个iPhone应用程序,它可以查询一个服务器,转发我在Amazon SimpleDB中存储的数据。我有一个由不同用户提交的数据库表。我正在与Facebook交互以检索Facebook好友,并希望查询“提交”以查找好友的帖子,如:

SELECT * FROM submissions WHERE userID = '00123' OR userID = '00124' OR .... 
(通过完整的朋友列表)

我认为这种select语句会导致Amazon查询受限-

[每个Select表达式的最大比较次数:20]

你能想出一个方法,用SimpleDB优雅地完成这个任务吗? 我不想做一大堆20人的问题。 或者,我是否需要移动到其他数据库包,然后执行跨表查询


谢谢

您需要IN子句或临时表的联接。不幸的是,AmazonSimpleDB有其局限性。正因为这个原因,我们放弃了一个有前途的项目。在切换设备之前,我们使用了多线程和NextToken功能


您可以对SimpleDB执行并行(多线程)查询以获得提交,每个查询最多查找20个用户ID,然后将结果合并到一个列表中。不过,也许是时候考虑切换到MySQL或SQLServer了,可以上传一个IDS列表作为临时表,然后做一个简单的连接来获得结果。

< P>有一个用SimuldB做的方法,但是它不雅致,这更像是一种黑客行为,因为它要求您在提交项目中人工复制userid属性

这是基于这样一个事实,即虽然每个IN谓词只能有20个比较,但是如果每个IN谓词都命名不同的属性,则可以有20个IN谓词。因此,向表单的提交项目添加其他合成属性:

userID='00123'userID_2='00123'userID_3='00123'userID_4='00123'。。。用户ID_20='00123'

对于给定的提交,它们都具有相同的值。然后,您可以通过一个查询获取最多400个好友的提交:

SELECT * FROM submissions 
WHERE userID IN('00120','00121',...,'00139') OR
    `userID_2` IN('00140','00141',...,'00159') OR
    `userID_3` IN('00160','00161',...,'00179') OR
    `userID_4` IN('00180','00181',...,'00199') OR
    ...
    `userID_20` IN('00300','00301',...,'00319')
您可以在创建提交时填充19个额外属性(如果您有备用属性),并且提交的用户听起来不会改变。另外,您可能希望显式地命名要返回的属性(而不是使用*),因为现在在返回数据集中有19个您不关心的属性

从数据模型的角度来看,这显然是一种黑客行为。但话说回来,对于拥有400个或更少好友的用户,它提供了您想要的东西:一个查询,这样您就可以按日期或其他条件进行限制,按最近的排序,页面浏览结果等。不幸的是,400的容量无法容纳所有facebook用户的好友列表。因此,您可能仍然需要为大型好友列表实现一个多查询解决方案

我的建议是,如果SimuldB适合你的应用程序的需要,除了这个问题,然后考虑使用HACK。但是,如果您需要重复执行类似的操作,那么SimpleDB可能不是最佳选择。

我创建了,并且碰巧有一些实用程序代码用于拆分和并行运行多个select查询,同时将每个select的in子句限制为20个值。我可能会在下一个Savant版本中发布这段代码,但这里是为那些认为它有用的人准备的:

    /// <summary>
    /// Invokes select queries that use parameter lists (with IN clauses) by splitting the parameter list
    /// across multiple invocations that are invoked in parallel.
    /// </summary>
    /// <typeparam name="T">The item type</typeparam>
    /// <typeparam name="P">The select parameter type</typeparam>
    /// <param name="savant">The savant instance.</param>
    /// <param name="command">The command.</param>
    /// <param name="paramValues">The param values.</param>
    /// <param name="paramName">Name of the param.</param>
    /// <returns></returns>
    public static List<T> SelectWithList<T,P>(ISimpleSavantU savant, SelectCommand<T> command, List<P> paramValues, string paramName)
    {
        var allValues = SelectAttributesWithList(savant, command, paramValues, paramName);
        var typedValues = new List<T>();
        foreach (var values in allValues)
        {
            typedValues.Add((T)PropertyValues.CreateItem(typeof (T), values));
        }
        return typedValues;
    }

    /// <summary>
    /// Invokes select queries that use parameter lists (with IN clauses) by splitting the parameter list
    /// across multiple invocations that are invoked in parallel.
    /// </summary>
    /// <typeparam name="P">The select parameter type</typeparam>
    /// <param name="savant">The savant instance.</param>
    /// <param name="command">The command.</param>
    /// <param name="paramValues">The param values.</param>
    /// <param name="paramName">Name of the param.</param>
    /// <returns></returns>
    public static List<PropertyValues> SelectAttributesWithList<P>(ISimpleSavantU savant, SelectCommand command, List<P> paramValues, string paramName)
    {
        Arg.CheckNull("savant", savant);
        Arg.CheckNull("command", command);
        Arg.CheckNull("paramValues", paramValues);
        Arg.CheckNullOrEmpty("paramName", paramName);

        var allValues = new List<PropertyValues>();
        if (paramValues.Count == 0)
        {
            return allValues;
        }

        var results = new List<IAsyncResult>();
        do
        {
            var currentParams = paramValues.Skip(results.Count * MaxValueTestsPerSimpleDbQuery).Take(MaxValueTestsPerSimpleDbQuery).ToList();
            if (!currentParams.Any())
            {
                break;
            }
            var currentCommand = Clone(command);
            currentCommand.Reset();
            var parameter = currentCommand.GetParameter(paramName);
            parameter.Values.Clear();
            parameter.Values.AddRange(currentParams.Select(e => (object)e));
            var result = savant.BeginSelectAttributes(currentCommand, null, null);
            results.Add(result);
        } while (true);

        foreach (var result in results)
        {
            var values = ((ISimpleSavant2)savant).EndSelectAttributes(result);
            allValues.AddRange(values);
        }

        return allValues;
    }

    private static SelectCommand Clone(SelectCommand command)
    {
        var newParameters = new List<CommandParameter>();
        foreach (var parameter in command.Parameters)
        {
            var newParameter = new CommandParameter(parameter.Name, parameter.PropertyName, null);
            newParameter.Values.Clear();
            newParameters.Add(newParameter);
        }
        var newCommand = new SelectCommand(command.Mapping, command.CommandText, newParameters.ToArray())
            {
                MaxResultPages = command.MaxResultPages
            };
        return newCommand;
    }
//
///通过拆分参数列表调用使用参数列表(带IN子句)的select查询
///跨并行调用的多个调用。
/// 
///项目类型
///选择参数类型
///学者的例子。
///命令。
///参数值。
///参数的名称。
/// 
公共静态列表SelectWithList(ISimpleSavantU savant,SelectCommand命令,列表

paramValues,字符串paramName) { var allValues=SelectAttributesWithList(savant、command、paramValues、paramName); var typedValues=新列表(); foreach(所有值中的var值) { 添加((T)propertyvalue.CreateItem(typeof(T),values)); } 返回类型值; } /// ///通过拆分参数列表调用使用参数列表(带IN子句)的select查询 ///跨并行调用的多个调用。 /// ///选择参数类型 ///学者的例子。 ///命令。 ///参数值。 ///参数的名称。 /// 公共静态列表使用列表选择属性(ISimpleSavantU savant,SelectCommand命令,列表

参数值,字符串参数名) { 参数CheckNull(“savant”,savant); 参数CheckNull(“命令”,命令); 参数CheckNull(“paramValues”,paramValues); 参数CheckNullOrEmpty(“paramName”,paramName); var allValues=新列表(); 如果(paramValues.Count==0) { 返回所有值; } var results=新列表(); 做 { var currentParams=paramValues.Skip(results.Count*MaxValueTestsPerSimpleDbQuery).Take(MaxValueTestsPerSimpleDbQuery).ToList(); 如果(!currentParams.Any()) { 打破 } var currentCommand=Clone(命令); currentCommand.Reset(); var参数=currentCommand.GetParameter(paramName); parameter.Values.Clear(); parameter.Values.AddRange(currentParams.Select(e=>(object)e)); var result=savant.BeginSelectAttributes(currentCommand,null,null); 结果。添加(结果); }虽然(正确); foreach(结果中的var结果) { 变量值=((ISimpleSavant2)savant).EndSelectAttributes(结果); allValues.AddRange(值); } 返回所有值; } 专用静态选择命令克隆(选择